@umami/shiso 1.18.0 → 1.19.0
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/chunks/App.js +1081 -47
- package/dist/chunks/architectureDiagram-5GKGNRK7.js +1 -1
- package/dist/chunks/chunk-GMAD6QVW.js +1 -1
- package/dist/chunks/cose-bilkent-JH36ORCC.js +1 -1
- package/dist/chunks/dist.js +1 -1
- package/dist/chunks/docs.js +183 -8
- package/dist/chunks/ganttDiagram-EL5Y4UJY.js +1 -1
- package/dist/chunks/src.js +1 -1
- package/dist/components.js +1 -1
- package/dist/entry-client.js +1 -1
- package/dist/entry-server.js +1 -1
- package/docs.schema.json +1164 -1135
- package/package.json +1 -2
- package/scripts/check-content.mjs +42 -15
- package/scripts/expand-openapi-navigation.mjs +47 -21
- package/scripts/generate-openapi.mjs +36 -11
- package/scripts/generate-search-index.mjs +19 -18
- package/scripts/lib/openapi-project.mjs +197 -0
- package/scripts/lib/openapi.mjs +257 -111
- package/scripts/lib/request-samples.mjs +323 -0
- package/scripts/load-docs-config.mjs +23 -15
- package/scripts/prerender.mjs +17 -14
- package/scripts/vite-docs-config.mjs +1 -0
- package/src/components/ApiPlayground.tsx +522 -0
- package/src/components/DocContent.tsx +15 -4
- package/src/components/Docs.tsx +18 -3
- package/src/components/LanguageSwitcher.tsx +26 -30
- package/src/components/OpenApiOperation.tsx +58 -12
- package/src/components/OpenApiSchema.tsx +97 -0
- package/src/components/SideNav.tsx +2 -2
- package/src/lib/openapi.generated.ts +2 -1
- package/src/lib/openapi.ts +104 -10
- package/src/lib/site-model.ts +12 -0
- package/src/lib/translations/de.json +26 -1
- package/src/lib/translations/en.json +26 -1
- package/src/lib/translations/es.json +26 -1
- package/src/lib/translations/fr.json +26 -1
- package/src/lib/translations/ja.json +26 -1
- package/src/lib/translations/zh-Hans.json +26 -1
- package/src/lib/translations/zh-Hant.json +26 -1
- package/src/lib/types.ts +89 -5
- package/types/labels.d.ts +25 -0
- package/vite.config.ts +3 -4
- package/CHANGELOG.md +0 -8
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
import { ApiPlayground } from '@/components/ApiPlayground';
|
|
1
2
|
import { CodeBlock } from '@/components/CodeBlock';
|
|
2
3
|
import { Badge } from '@/components/docs/Badge';
|
|
3
4
|
import { CodeGroup } from '@/components/docs/CodeGroup';
|
|
4
5
|
import { Expandable } from '@/components/docs/Expandable';
|
|
5
6
|
import { PropertiesTable } from '@/components/docs/PropertiesTable';
|
|
6
7
|
import { useLabels } from '@/lib/label-context';
|
|
7
|
-
import {
|
|
8
|
-
|
|
8
|
+
import {
|
|
9
|
+
operationParameterSections,
|
|
10
|
+
operationSections,
|
|
11
|
+
securityFieldName,
|
|
12
|
+
securityForLocation,
|
|
13
|
+
statusColor,
|
|
14
|
+
} from '@/lib/openapi';
|
|
15
|
+
import type { NormalizedOperation, SchemaNode, SecurityScheme, ThemeLabels } from '@/lib/types';
|
|
16
|
+
import { securityPlaceholder } from '../../scripts/lib/request-samples.mjs';
|
|
9
17
|
|
|
10
18
|
function FieldChildren({ node }: { node: SchemaNode }) {
|
|
11
19
|
const labels = useLabels();
|
|
@@ -104,27 +112,63 @@ function HighlightedCode({
|
|
|
104
112
|
);
|
|
105
113
|
}
|
|
106
114
|
|
|
115
|
+
/** How a credential is sent, e.g. "Bearer <token>" or "<api-key>". */
|
|
116
|
+
function credentialExample(scheme: SecurityScheme): string {
|
|
117
|
+
const placeholder = securityPlaceholder(scheme);
|
|
118
|
+
if (scheme.type === 'apiKey') return placeholder;
|
|
119
|
+
const prefix =
|
|
120
|
+
scheme.type === 'http' && scheme.scheme && scheme.scheme !== 'bearer'
|
|
121
|
+
? scheme.scheme.charAt(0).toUpperCase() + scheme.scheme.slice(1)
|
|
122
|
+
: 'Bearer';
|
|
123
|
+
return `${prefix} ${placeholder}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
107
126
|
export interface OpenApiOperationProps {
|
|
108
127
|
operation: NormalizedOperation;
|
|
128
|
+
/** Renders the "Try it" panel ahead of the reference; carries the proxy setting. */
|
|
129
|
+
playground?: { proxy?: string } | false;
|
|
109
130
|
}
|
|
110
131
|
|
|
111
132
|
/** The generated reference for one API operation, rendered under the page body. */
|
|
112
|
-
export function OpenApiOperation({
|
|
133
|
+
export function OpenApiOperation({
|
|
134
|
+
operation,
|
|
135
|
+
playground: requested = false,
|
|
136
|
+
}: OpenApiOperationProps) {
|
|
113
137
|
const labels = useLabels();
|
|
114
|
-
|
|
115
|
-
const
|
|
138
|
+
// Webhooks describe requests the API sends, so there is nothing to try.
|
|
139
|
+
const playground = operation.webhook ? false : requested;
|
|
140
|
+
const options = { playground: !!playground };
|
|
141
|
+
const sectionEntries = operationSections(operation, labels, options);
|
|
142
|
+
// Ids come from the untranslated names so anchors are stable across locales.
|
|
143
|
+
const sections = new Map(
|
|
144
|
+
operationSections(operation, undefined, options).map(entry => [entry.name, entry.id]),
|
|
145
|
+
);
|
|
146
|
+
const parameterSections = operationParameterSections(operation, labels);
|
|
147
|
+
const parameterOffset = playground ? 1 : 0;
|
|
116
148
|
|
|
117
149
|
return (
|
|
118
150
|
<div className="docs-markdown">
|
|
119
|
-
{
|
|
151
|
+
{playground && (
|
|
152
|
+
<section>
|
|
153
|
+
<h2 id={sections.get('Try it')}>{labels.apiPlayground}</h2>
|
|
154
|
+
<ApiPlayground operation={operation} proxy={playground.proxy} />
|
|
155
|
+
</section>
|
|
156
|
+
)}
|
|
157
|
+
{parameterSections.map(({ location, name }, index) => (
|
|
120
158
|
<section key={location}>
|
|
121
|
-
<h2 id={sectionEntries[index].id}>{name}</h2>
|
|
159
|
+
<h2 id={sectionEntries[index + parameterOffset].id}>{name}</h2>
|
|
122
160
|
<PropertiesTable>
|
|
123
|
-
{location
|
|
124
|
-
<PropertiesTable.Row
|
|
125
|
-
{
|
|
161
|
+
{securityForLocation(operation, location).map(scheme => (
|
|
162
|
+
<PropertiesTable.Row
|
|
163
|
+
key={`security:${scheme.name}`}
|
|
164
|
+
name={securityFieldName(scheme)}
|
|
165
|
+
type="string"
|
|
166
|
+
required
|
|
167
|
+
>
|
|
168
|
+
{scheme.description || labels.apiCredentials}{' '}
|
|
169
|
+
<code>{credentialExample(scheme)}</code>.
|
|
126
170
|
</PropertiesTable.Row>
|
|
127
|
-
)}
|
|
171
|
+
))}
|
|
128
172
|
{operation.parameters[location].map(parameter => (
|
|
129
173
|
<PropertiesTable.Row
|
|
130
174
|
key={parameter.name}
|
|
@@ -143,7 +187,9 @@ export function OpenApiOperation({ operation }: OpenApiOperationProps) {
|
|
|
143
187
|
))}
|
|
144
188
|
{operation.requestBody && (
|
|
145
189
|
<section>
|
|
146
|
-
<h2 id={sections.get('Request body')}>
|
|
190
|
+
<h2 id={sections.get(operation.webhook ? 'Payload' : 'Request body')}>
|
|
191
|
+
{operation.webhook ? labels.apiPayload : labels.apiRequestBody}
|
|
192
|
+
</h2>
|
|
147
193
|
<SchemaFields node={operation.requestBody.schema} />
|
|
148
194
|
{operation.requestBody.example && (
|
|
149
195
|
<HighlightedCode
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { CodeBlock } from '@/components/CodeBlock';
|
|
2
|
+
import { Expandable } from '@/components/docs/Expandable';
|
|
3
|
+
import { PropertiesTable } from '@/components/docs/PropertiesTable';
|
|
4
|
+
import { useLabels } from '@/lib/label-context';
|
|
5
|
+
import { schemaSections } from '@/lib/openapi';
|
|
6
|
+
import type { SchemaNode, SchemaPage, ThemeLabels } from '@/lib/types';
|
|
7
|
+
|
|
8
|
+
function FieldChildren({ node }: { node: SchemaNode }) {
|
|
9
|
+
const labels = useLabels();
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
{node.description}
|
|
13
|
+
{node.enum && node.enum.length > 0 && (
|
|
14
|
+
<div className="mt-1">
|
|
15
|
+
{labels.fieldOptions}{' '}
|
|
16
|
+
{node.enum.map((value, index) => (
|
|
17
|
+
<span key={value}>
|
|
18
|
+
{index > 0 && ', '}
|
|
19
|
+
<code>{value}</code>
|
|
20
|
+
</span>
|
|
21
|
+
))}
|
|
22
|
+
</div>
|
|
23
|
+
)}
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function SchemaTable({ nodes, labels }: { nodes: SchemaNode[]; labels: ThemeLabels }) {
|
|
29
|
+
return (
|
|
30
|
+
<PropertiesTable>
|
|
31
|
+
{nodes.map(node => (
|
|
32
|
+
<PropertiesTable.Row
|
|
33
|
+
key={node.name || node.type}
|
|
34
|
+
name={node.name || node.type}
|
|
35
|
+
type={node.type}
|
|
36
|
+
required={node.required}
|
|
37
|
+
deprecated={node.deprecated}
|
|
38
|
+
default={node.default}
|
|
39
|
+
details={
|
|
40
|
+
node.children?.length ? (
|
|
41
|
+
<Expandable
|
|
42
|
+
title={
|
|
43
|
+
node.type === 'oneOf' || node.type === 'anyOf'
|
|
44
|
+
? labels.allowedTypes
|
|
45
|
+
: labels.properties
|
|
46
|
+
}
|
|
47
|
+
>
|
|
48
|
+
<SchemaTable nodes={node.children} labels={labels} />
|
|
49
|
+
</Expandable>
|
|
50
|
+
) : undefined
|
|
51
|
+
}
|
|
52
|
+
>
|
|
53
|
+
<FieldChildren node={node} />
|
|
54
|
+
</PropertiesTable.Row>
|
|
55
|
+
))}
|
|
56
|
+
</PropertiesTable>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface OpenApiSchemaProps {
|
|
61
|
+
page: SchemaPage;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** The generated reference for one named component schema. */
|
|
65
|
+
export function OpenApiSchema({ page }: OpenApiSchemaProps) {
|
|
66
|
+
const labels = useLabels();
|
|
67
|
+
const sections = new Map(schemaSections(page, labels).map(entry => [entry.id, entry.name]));
|
|
68
|
+
const properties = sections.get('properties');
|
|
69
|
+
const example = sections.get('example');
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div className="docs-markdown">
|
|
73
|
+
{properties && (
|
|
74
|
+
<section>
|
|
75
|
+
<h2 id="properties">{properties}</h2>
|
|
76
|
+
<SchemaTable nodes={page.schema.children ?? []} labels={labels} />
|
|
77
|
+
</section>
|
|
78
|
+
)}
|
|
79
|
+
{example && page.example && (
|
|
80
|
+
<section>
|
|
81
|
+
<h2 id="example">{example}</h2>
|
|
82
|
+
<CodeBlock data-language="json" data-title={page.name}>
|
|
83
|
+
{page.exampleHtml ? (
|
|
84
|
+
<code
|
|
85
|
+
className="language-json"
|
|
86
|
+
// biome-ignore lint/security/noDangerouslySetInnerHtml: build-time generated markup from the project's own OpenAPI spec.
|
|
87
|
+
dangerouslySetInnerHTML={{ __html: page.exampleHtml }}
|
|
88
|
+
/>
|
|
89
|
+
) : (
|
|
90
|
+
<code className="language-json">{page.example}</code>
|
|
91
|
+
)}
|
|
92
|
+
</CodeBlock>
|
|
93
|
+
</section>
|
|
94
|
+
)}
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -8,7 +8,7 @@ import { Button } from '@/components/ui/button';
|
|
|
8
8
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
|
9
9
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
10
10
|
import { flattenNav, isNodeHidden } from '@/lib/docs-config';
|
|
11
|
-
import { methodColor } from '@/lib/openapi';
|
|
11
|
+
import { methodBadgeText, methodColor } from '@/lib/openapi';
|
|
12
12
|
import type { DocsTab, NavGroupNode, NavNode } from '@/lib/types';
|
|
13
13
|
import { cn } from '@/lib/utils';
|
|
14
14
|
|
|
@@ -281,7 +281,7 @@ function NavNodes({
|
|
|
281
281
|
size="xs"
|
|
282
282
|
className="w-10 shrink-0 justify-center whitespace-nowrap font-mono"
|
|
283
283
|
>
|
|
284
|
-
{method
|
|
284
|
+
{methodBadgeText(method)}
|
|
285
285
|
</MethodBadge>
|
|
286
286
|
) : null}
|
|
287
287
|
{label}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Build-time alias target. Shiso replaces this module with the project's generated operations.
|
|
2
|
-
import type { NormalizedOperation } from '@/lib/types';
|
|
2
|
+
import type { NormalizedOperation, SchemaPage } from '@/lib/types';
|
|
3
3
|
|
|
4
4
|
export const OPENAPI_OPERATIONS: Record<string, NormalizedOperation> = {};
|
|
5
|
+
export const OPENAPI_SCHEMAS: Record<string, SchemaPage> = {};
|
package/src/lib/openapi.ts
CHANGED
|
@@ -6,9 +6,18 @@ import { englishLabels } from '@/lib/labels';
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { BadgeColor } from '@/components/docs/Badge';
|
|
9
|
-
import { OPENAPI_OPERATIONS } from '@/lib/openapi.generated';
|
|
9
|
+
import { OPENAPI_OPERATIONS, OPENAPI_SCHEMAS } from '@/lib/openapi.generated';
|
|
10
10
|
import { createSlugger } from '@/lib/slug';
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
ApiPlaygroundDisplay,
|
|
13
|
+
DocFrontmatter,
|
|
14
|
+
NormalizedOperation,
|
|
15
|
+
ResolvedApiPlayground,
|
|
16
|
+
SchemaPage,
|
|
17
|
+
SecurityScheme,
|
|
18
|
+
ThemeLabels,
|
|
19
|
+
TocEntry,
|
|
20
|
+
} from '@/lib/types';
|
|
12
21
|
|
|
13
22
|
export const METHOD_COLORS: Record<string, BadgeColor> = {
|
|
14
23
|
GET: 'green',
|
|
@@ -16,8 +25,33 @@ export const METHOD_COLORS: Record<string, BadgeColor> = {
|
|
|
16
25
|
PUT: 'orange',
|
|
17
26
|
PATCH: 'purple',
|
|
18
27
|
DELETE: 'red',
|
|
28
|
+
WEBHOOK: 'yellow',
|
|
19
29
|
};
|
|
20
30
|
|
|
31
|
+
const HTTP_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE']);
|
|
32
|
+
|
|
33
|
+
/** Short sidebar badge text for a method. */
|
|
34
|
+
export function methodBadgeText(method: string): string {
|
|
35
|
+
if (method === 'DELETE') return 'DEL';
|
|
36
|
+
if (method === 'WEBHOOK') return 'HOOK';
|
|
37
|
+
return method;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Normalizes an `openapi:` frontmatter value into a lookup key. Mirrors
|
|
42
|
+
* normalizeOperationKey in scripts/lib/openapi.mjs: the method (or "webhook")
|
|
43
|
+
* is uppercased and an optional leading spec qualifier is kept verbatim.
|
|
44
|
+
*/
|
|
45
|
+
export function normalizeOperationKey(value: unknown): string | undefined {
|
|
46
|
+
if (typeof value !== 'string' || !value.trim()) return undefined;
|
|
47
|
+
const [first, ...rest] = value.trim().split(/\s+/);
|
|
48
|
+
if (!rest.length) return undefined;
|
|
49
|
+
const upper = first.toUpperCase();
|
|
50
|
+
if (upper === 'WEBHOOK' || HTTP_METHODS.has(upper)) return `${upper} ${rest.join(' ')}`;
|
|
51
|
+
const inner = normalizeOperationKey(rest.join(' '));
|
|
52
|
+
return inner ? `${first} ${inner}` : undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
21
55
|
export function methodColor(method?: string): BadgeColor {
|
|
22
56
|
return (method && METHOD_COLORS[method.toUpperCase()]) || 'gray';
|
|
23
57
|
}
|
|
@@ -29,14 +63,68 @@ export function statusColor(status: string): BadgeColor {
|
|
|
29
63
|
return 'gray';
|
|
30
64
|
}
|
|
31
65
|
|
|
66
|
+
/** Options that change which generated sections an operation page renders. */
|
|
67
|
+
export interface OperationSectionOptions {
|
|
68
|
+
/** Whether the "Try it" panel renders ahead of the reference sections. */
|
|
69
|
+
playground?: boolean;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Resolves the effective playground display for a page: the frontmatter
|
|
74
|
+
* `playground` value wins over `api.playground.display`.
|
|
75
|
+
*/
|
|
76
|
+
export function resolvePlaygroundDisplay(
|
|
77
|
+
playground: ResolvedApiPlayground,
|
|
78
|
+
frontmatter?: DocFrontmatter,
|
|
79
|
+
): ApiPlaygroundDisplay {
|
|
80
|
+
const override = frontmatter?.playground;
|
|
81
|
+
if (override === 'interactive' || override === 'simple' || override === 'none') {
|
|
82
|
+
return override;
|
|
83
|
+
}
|
|
84
|
+
return playground.display;
|
|
85
|
+
}
|
|
86
|
+
|
|
32
87
|
/** Looks up the operation bound by an `openapi:` frontmatter value. */
|
|
33
88
|
export function getOperation(key?: unknown): NormalizedOperation | undefined {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
89
|
+
const normalized = normalizeOperationKey(key);
|
|
90
|
+
return normalized ? OPENAPI_OPERATIONS[normalized] : undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Looks up the schema bound by an `openapi-schema:` frontmatter value. */
|
|
94
|
+
export function getSchema(key?: unknown): SchemaPage | undefined {
|
|
95
|
+
if (typeof key !== 'string' || !key.trim()) return undefined;
|
|
96
|
+
return OPENAPI_SCHEMAS[key.trim().split(/\s+/).join(' ')];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Section headings for a schema page, in render order. Mirrors schemaAnchors
|
|
101
|
+
* in scripts/lib/openapi.mjs.
|
|
102
|
+
*/
|
|
103
|
+
export function schemaSections(page: SchemaPage, labels: ThemeLabels = englishLabels): TocEntry[] {
|
|
104
|
+
return [
|
|
105
|
+
...(page.schema.children?.length
|
|
106
|
+
? [{ name: labels.apiSchemaProperties, id: 'properties', size: 2 }]
|
|
107
|
+
: []),
|
|
108
|
+
...(page.example ? [{ name: labels.apiExample, id: 'example', size: 2 }] : []),
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Where a security scheme's credential travels: a header unless it is a query or cookie API key. */
|
|
113
|
+
export function securityLocation(scheme: SecurityScheme): 'header' | 'query' | 'cookie' {
|
|
114
|
+
return scheme.type === 'apiKey' && scheme.in ? scheme.in : 'header';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Security schemes that are sent in the given parameter location. */
|
|
118
|
+
export function securityForLocation(
|
|
119
|
+
operation: NormalizedOperation,
|
|
120
|
+
location: 'header' | 'path' | 'query' | 'cookie',
|
|
121
|
+
): SecurityScheme[] {
|
|
122
|
+
return operation.security.filter(scheme => securityLocation(scheme) === location);
|
|
123
|
+
}
|
|
37
124
|
|
|
38
|
-
|
|
39
|
-
|
|
125
|
+
/** Display name of the header, query, or cookie entry a scheme adds. */
|
|
126
|
+
export function securityFieldName(scheme: SecurityScheme): string {
|
|
127
|
+
return scheme.type === 'apiKey' ? scheme.paramName || scheme.name : 'Authorization';
|
|
40
128
|
}
|
|
41
129
|
|
|
42
130
|
export function hasParameters(operation: NormalizedOperation): boolean {
|
|
@@ -61,7 +149,7 @@ export function operationParameterSections(
|
|
|
61
149
|
return groups.filter(
|
|
62
150
|
({ location }) =>
|
|
63
151
|
operation.parameters[location].length > 0 ||
|
|
64
|
-
(location
|
|
152
|
+
securityForLocation(operation, location).length > 0,
|
|
65
153
|
);
|
|
66
154
|
}
|
|
67
155
|
|
|
@@ -73,18 +161,24 @@ export function operationParameterSections(
|
|
|
73
161
|
export function operationSections(
|
|
74
162
|
operation: NormalizedOperation,
|
|
75
163
|
labels: ThemeLabels = englishLabels,
|
|
164
|
+
options: OperationSectionOptions = {},
|
|
76
165
|
): TocEntry[] {
|
|
77
166
|
const slugger = createSlugger();
|
|
167
|
+
const playground = options.playground && !operation.webhook;
|
|
78
168
|
const names = [
|
|
169
|
+
playground ? 'Try it' : undefined,
|
|
79
170
|
...operationParameterSections(operation).map(section => section.name),
|
|
80
|
-
operation.requestBody ? 'Request body' : undefined,
|
|
171
|
+
operation.requestBody ? (operation.webhook ? 'Payload' : 'Request body') : undefined,
|
|
81
172
|
operation.responses.length ? 'Responses' : undefined,
|
|
82
173
|
operation.samples.length ? 'Code samples' : undefined,
|
|
83
174
|
].filter((name): name is string => Boolean(name));
|
|
84
175
|
|
|
85
176
|
const translated = [
|
|
177
|
+
...(playground ? [labels.apiPlayground] : []),
|
|
86
178
|
...operationParameterSections(operation, labels).map(section => section.name),
|
|
87
|
-
...(operation.requestBody
|
|
179
|
+
...(operation.requestBody
|
|
180
|
+
? [operation.webhook ? labels.apiPayload : labels.apiRequestBody]
|
|
181
|
+
: []),
|
|
88
182
|
...(operation.responses.length ? [labels.apiResponses] : []),
|
|
89
183
|
...(operation.samples.length ? [labels.apiCodeSamples] : []),
|
|
90
184
|
];
|
package/src/lib/site-model.ts
CHANGED
|
@@ -48,6 +48,17 @@ function normalizeNavbar(config: DocsConfig['navbar']): NormalizedNavbar | null
|
|
|
48
48
|
return links.length || primary ? { links, primary } : null;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
function normalizePlayground(config: DocsConfig['api']): SiteModel['api']['playground'] {
|
|
52
|
+
const playground = config?.playground;
|
|
53
|
+
const display =
|
|
54
|
+
playground?.display === 'simple' || playground?.display === 'none'
|
|
55
|
+
? playground.display
|
|
56
|
+
: 'interactive';
|
|
57
|
+
const proxy = playground?.proxy?.trim() || undefined;
|
|
58
|
+
|
|
59
|
+
return proxy ? { display, proxy } : { display };
|
|
60
|
+
}
|
|
61
|
+
|
|
51
62
|
function normalizeFooter(config: DocsConfig['footer']): NormalizedFooter | null {
|
|
52
63
|
const socials = (config?.socials || []).filter(link => !!link?.href).map(normalizeLink);
|
|
53
64
|
const links = (config?.links || [])
|
|
@@ -112,6 +123,7 @@ export function resolveSiteModel(
|
|
|
112
123
|
drilldown: config.interaction?.drilldown,
|
|
113
124
|
locale: shiso?.locale || 'en-US',
|
|
114
125
|
labels: resolveLabels(shiso?.locale || 'en-US', shiso?.translations),
|
|
126
|
+
api: { playground: normalizePlayground(config.api) },
|
|
115
127
|
docs,
|
|
116
128
|
};
|
|
117
129
|
}
|
|
@@ -70,5 +70,30 @@
|
|
|
70
70
|
"apiCodeSamples": "Codebeispiele",
|
|
71
71
|
"apiExampleRequest": "Beispielanfrage",
|
|
72
72
|
"apiExampleResponse": "Beispiel für {status}",
|
|
73
|
-
"apiCredentials": "Anmeldedaten, z. B."
|
|
73
|
+
"apiCredentials": "Anmeldedaten, z. B.",
|
|
74
|
+
"apiPlayground": "Ausprobieren",
|
|
75
|
+
"apiServer": "Server",
|
|
76
|
+
"apiAuthorization": "Autorisierung",
|
|
77
|
+
"apiUsername": "Benutzername",
|
|
78
|
+
"apiPassword": "Passwort",
|
|
79
|
+
"apiToken": "Token",
|
|
80
|
+
"apiApiKey": "API-Schlüssel",
|
|
81
|
+
"apiBody": "Body",
|
|
82
|
+
"apiSend": "Anfrage senden",
|
|
83
|
+
"apiSending": "Wird gesendet...",
|
|
84
|
+
"apiCancel": "Abbrechen",
|
|
85
|
+
"apiRequest": "Anfrage",
|
|
86
|
+
"apiResponse": "Antwort",
|
|
87
|
+
"apiResponseHeaders": "Antwort-Header",
|
|
88
|
+
"apiResponseBody": "Antwort-Body",
|
|
89
|
+
"apiNoResponse": "Senden Sie eine Anfrage, um die Antwort zu sehen.",
|
|
90
|
+
"apiRequestFailed": "Die Anfrage konnte nicht gesendet werden. Die API blockiert möglicherweise Browser-Anfragen (CORS) oder ist nicht erreichbar; konfigurieren Sie einen Playground-Proxy oder führen Sie das cURL-Beispiel im Terminal aus.",
|
|
91
|
+
"apiRequestTimedOut": "Zeitüberschreitung der Anfrage.",
|
|
92
|
+
"apiCookiesUnsupported": "Cookie-Parameter können im Browser nicht gesetzt werden und werden nicht gesendet.",
|
|
93
|
+
"apiOptional": "optional",
|
|
94
|
+
"apiElapsed": "{ms} ms",
|
|
95
|
+
"apiCredentialsStored": "Zugangsdaten bleiben in diesem Browser-Tab und werden nur an die API gesendet.",
|
|
96
|
+
"apiPayload": "Nutzdaten",
|
|
97
|
+
"apiSchemaProperties": "Eigenschaften",
|
|
98
|
+
"apiExample": "Beispiel"
|
|
74
99
|
}
|
|
@@ -70,5 +70,30 @@
|
|
|
70
70
|
"apiCodeSamples": "Code samples",
|
|
71
71
|
"apiExampleRequest": "Example request",
|
|
72
72
|
"apiExampleResponse": "{status} example",
|
|
73
|
-
"apiCredentials": "Authentication credentials, e.g."
|
|
73
|
+
"apiCredentials": "Authentication credentials, e.g.",
|
|
74
|
+
"apiPlayground": "Try it",
|
|
75
|
+
"apiServer": "Server",
|
|
76
|
+
"apiAuthorization": "Authorization",
|
|
77
|
+
"apiUsername": "Username",
|
|
78
|
+
"apiPassword": "Password",
|
|
79
|
+
"apiToken": "Token",
|
|
80
|
+
"apiApiKey": "API key",
|
|
81
|
+
"apiBody": "Body",
|
|
82
|
+
"apiSend": "Send request",
|
|
83
|
+
"apiSending": "Sending...",
|
|
84
|
+
"apiCancel": "Cancel",
|
|
85
|
+
"apiRequest": "Request",
|
|
86
|
+
"apiResponse": "Response",
|
|
87
|
+
"apiResponseHeaders": "Response headers",
|
|
88
|
+
"apiResponseBody": "Response body",
|
|
89
|
+
"apiNoResponse": "Send a request to see the response.",
|
|
90
|
+
"apiRequestFailed": "The request could not be sent. The API may block browser requests (CORS) or be unreachable; configure a playground proxy or run the cURL sample from a terminal.",
|
|
91
|
+
"apiRequestTimedOut": "The request timed out.",
|
|
92
|
+
"apiCookiesUnsupported": "Cookie parameters cannot be set from the browser and are not sent.",
|
|
93
|
+
"apiOptional": "optional",
|
|
94
|
+
"apiElapsed": "{ms} ms",
|
|
95
|
+
"apiCredentialsStored": "Credentials stay in this browser tab and are never sent anywhere except the API.",
|
|
96
|
+
"apiPayload": "Payload",
|
|
97
|
+
"apiSchemaProperties": "Properties",
|
|
98
|
+
"apiExample": "Example"
|
|
74
99
|
}
|
|
@@ -70,5 +70,30 @@
|
|
|
70
70
|
"apiCodeSamples": "Ejemplos de código",
|
|
71
71
|
"apiExampleRequest": "Ejemplo de solicitud",
|
|
72
72
|
"apiExampleResponse": "Ejemplo de {status}",
|
|
73
|
-
"apiCredentials": "Credenciales de autenticación, p. ej."
|
|
73
|
+
"apiCredentials": "Credenciales de autenticación, p. ej.",
|
|
74
|
+
"apiPlayground": "Probar",
|
|
75
|
+
"apiServer": "Servidor",
|
|
76
|
+
"apiAuthorization": "Autorización",
|
|
77
|
+
"apiUsername": "Usuario",
|
|
78
|
+
"apiPassword": "Contraseña",
|
|
79
|
+
"apiToken": "Token",
|
|
80
|
+
"apiApiKey": "Clave de API",
|
|
81
|
+
"apiBody": "Cuerpo",
|
|
82
|
+
"apiSend": "Enviar solicitud",
|
|
83
|
+
"apiSending": "Enviando...",
|
|
84
|
+
"apiCancel": "Cancelar",
|
|
85
|
+
"apiRequest": "Solicitud",
|
|
86
|
+
"apiResponse": "Respuesta",
|
|
87
|
+
"apiResponseHeaders": "Encabezados de respuesta",
|
|
88
|
+
"apiResponseBody": "Cuerpo de la respuesta",
|
|
89
|
+
"apiNoResponse": "Envía una solicitud para ver la respuesta.",
|
|
90
|
+
"apiRequestFailed": "No se pudo enviar la solicitud. Es posible que la API bloquee solicitudes del navegador (CORS) o no esté disponible; configura un proxy para el playground o ejecuta el ejemplo de cURL desde una terminal.",
|
|
91
|
+
"apiRequestTimedOut": "La solicitud excedió el tiempo de espera.",
|
|
92
|
+
"apiCookiesUnsupported": "Los parámetros de cookie no se pueden establecer desde el navegador y no se envían.",
|
|
93
|
+
"apiOptional": "opcional",
|
|
94
|
+
"apiElapsed": "{ms} ms",
|
|
95
|
+
"apiCredentialsStored": "Las credenciales permanecen en esta pestaña del navegador y solo se envían a la API.",
|
|
96
|
+
"apiPayload": "Carga útil",
|
|
97
|
+
"apiSchemaProperties": "Propiedades",
|
|
98
|
+
"apiExample": "Ejemplo"
|
|
74
99
|
}
|
|
@@ -70,5 +70,30 @@
|
|
|
70
70
|
"apiCodeSamples": "Exemples de code",
|
|
71
71
|
"apiExampleRequest": "Exemple de requête",
|
|
72
72
|
"apiExampleResponse": "Exemple {status}",
|
|
73
|
-
"apiCredentials": "Identifiants d’authentification, par exemple"
|
|
73
|
+
"apiCredentials": "Identifiants d’authentification, par exemple",
|
|
74
|
+
"apiPlayground": "Essayer",
|
|
75
|
+
"apiServer": "Serveur",
|
|
76
|
+
"apiAuthorization": "Autorisation",
|
|
77
|
+
"apiUsername": "Nom d’utilisateur",
|
|
78
|
+
"apiPassword": "Mot de passe",
|
|
79
|
+
"apiToken": "Jeton",
|
|
80
|
+
"apiApiKey": "Clé API",
|
|
81
|
+
"apiBody": "Corps",
|
|
82
|
+
"apiSend": "Envoyer la requête",
|
|
83
|
+
"apiSending": "Envoi...",
|
|
84
|
+
"apiCancel": "Annuler",
|
|
85
|
+
"apiRequest": "Requête",
|
|
86
|
+
"apiResponse": "Réponse",
|
|
87
|
+
"apiResponseHeaders": "En-têtes de réponse",
|
|
88
|
+
"apiResponseBody": "Corps de la réponse",
|
|
89
|
+
"apiNoResponse": "Envoyez une requête pour voir la réponse.",
|
|
90
|
+
"apiRequestFailed": "La requête n’a pas pu être envoyée. L’API bloque peut-être les requêtes du navigateur (CORS) ou est injoignable ; configurez un proxy pour le playground ou exécutez l’exemple cURL depuis un terminal.",
|
|
91
|
+
"apiRequestTimedOut": "La requête a expiré.",
|
|
92
|
+
"apiCookiesUnsupported": "Les paramètres de cookie ne peuvent pas être définis depuis le navigateur et ne sont pas envoyés.",
|
|
93
|
+
"apiOptional": "facultatif",
|
|
94
|
+
"apiElapsed": "{ms} ms",
|
|
95
|
+
"apiCredentialsStored": "Les identifiants restent dans cet onglet du navigateur et ne sont envoyés qu’à l’API.",
|
|
96
|
+
"apiPayload": "Charge utile",
|
|
97
|
+
"apiSchemaProperties": "Propriétés",
|
|
98
|
+
"apiExample": "Exemple"
|
|
74
99
|
}
|
|
@@ -70,5 +70,30 @@
|
|
|
70
70
|
"apiCodeSamples": "コードサンプル",
|
|
71
71
|
"apiExampleRequest": "リクエスト例",
|
|
72
72
|
"apiExampleResponse": "{status} の例",
|
|
73
|
-
"apiCredentials": "認証情報(例):"
|
|
73
|
+
"apiCredentials": "認証情報(例):",
|
|
74
|
+
"apiPlayground": "試してみる",
|
|
75
|
+
"apiServer": "サーバー",
|
|
76
|
+
"apiAuthorization": "認証",
|
|
77
|
+
"apiUsername": "ユーザー名",
|
|
78
|
+
"apiPassword": "パスワード",
|
|
79
|
+
"apiToken": "トークン",
|
|
80
|
+
"apiApiKey": "APIキー",
|
|
81
|
+
"apiBody": "ボディ",
|
|
82
|
+
"apiSend": "リクエストを送信",
|
|
83
|
+
"apiSending": "送信中...",
|
|
84
|
+
"apiCancel": "キャンセル",
|
|
85
|
+
"apiRequest": "リクエスト",
|
|
86
|
+
"apiResponse": "レスポンス",
|
|
87
|
+
"apiResponseHeaders": "レスポンスヘッダー",
|
|
88
|
+
"apiResponseBody": "レスポンスボディ",
|
|
89
|
+
"apiNoResponse": "リクエストを送信するとレスポンスが表示されます。",
|
|
90
|
+
"apiRequestFailed": "リクエストを送信できませんでした。APIがブラウザーからのリクエストをブロックしている(CORS)か、到達できない可能性があります。プレイグラウンドのプロキシを設定するか、cURLのサンプルをターミナルで実行してください。",
|
|
91
|
+
"apiRequestTimedOut": "リクエストがタイムアウトしました。",
|
|
92
|
+
"apiCookiesUnsupported": "Cookieパラメーターはブラウザーから設定できないため送信されません。",
|
|
93
|
+
"apiOptional": "省略可",
|
|
94
|
+
"apiElapsed": "{ms} ms",
|
|
95
|
+
"apiCredentialsStored": "認証情報はこのブラウザータブ内に保持され、API以外には送信されません。",
|
|
96
|
+
"apiPayload": "ペイロード",
|
|
97
|
+
"apiSchemaProperties": "プロパティ",
|
|
98
|
+
"apiExample": "例"
|
|
74
99
|
}
|
|
@@ -70,5 +70,30 @@
|
|
|
70
70
|
"apiCodeSamples": "代码示例",
|
|
71
71
|
"apiExampleRequest": "请求示例",
|
|
72
72
|
"apiExampleResponse": "{status} 示例",
|
|
73
|
-
"apiCredentials": "身份验证凭据,例如"
|
|
73
|
+
"apiCredentials": "身份验证凭据,例如",
|
|
74
|
+
"apiPlayground": "试一试",
|
|
75
|
+
"apiServer": "服务器",
|
|
76
|
+
"apiAuthorization": "授权",
|
|
77
|
+
"apiUsername": "用户名",
|
|
78
|
+
"apiPassword": "密码",
|
|
79
|
+
"apiToken": "令牌",
|
|
80
|
+
"apiApiKey": "API 密钥",
|
|
81
|
+
"apiBody": "请求体",
|
|
82
|
+
"apiSend": "发送请求",
|
|
83
|
+
"apiSending": "发送中...",
|
|
84
|
+
"apiCancel": "取消",
|
|
85
|
+
"apiRequest": "请求",
|
|
86
|
+
"apiResponse": "响应",
|
|
87
|
+
"apiResponseHeaders": "响应头",
|
|
88
|
+
"apiResponseBody": "响应体",
|
|
89
|
+
"apiNoResponse": "发送请求以查看响应。",
|
|
90
|
+
"apiRequestFailed": "无法发送请求。API 可能阻止了浏览器请求(CORS)或无法访问;请配置 playground 代理,或在终端中运行 cURL 示例。",
|
|
91
|
+
"apiRequestTimedOut": "请求超时。",
|
|
92
|
+
"apiCookiesUnsupported": "Cookie 参数无法在浏览器中设置,因此不会发送。",
|
|
93
|
+
"apiOptional": "可选",
|
|
94
|
+
"apiElapsed": "{ms} 毫秒",
|
|
95
|
+
"apiCredentialsStored": "凭据仅保留在此浏览器标签页中,只会发送给该 API。",
|
|
96
|
+
"apiPayload": "负载",
|
|
97
|
+
"apiSchemaProperties": "属性",
|
|
98
|
+
"apiExample": "示例"
|
|
74
99
|
}
|
|
@@ -70,5 +70,30 @@
|
|
|
70
70
|
"apiCodeSamples": "程式碼範例",
|
|
71
71
|
"apiExampleRequest": "請求範例",
|
|
72
72
|
"apiExampleResponse": "{status} 範例",
|
|
73
|
-
"apiCredentials": "驗證憑證,例如"
|
|
73
|
+
"apiCredentials": "驗證憑證,例如",
|
|
74
|
+
"apiPlayground": "試一試",
|
|
75
|
+
"apiServer": "伺服器",
|
|
76
|
+
"apiAuthorization": "授權",
|
|
77
|
+
"apiUsername": "使用者名稱",
|
|
78
|
+
"apiPassword": "密碼",
|
|
79
|
+
"apiToken": "權杖",
|
|
80
|
+
"apiApiKey": "API 金鑰",
|
|
81
|
+
"apiBody": "請求主體",
|
|
82
|
+
"apiSend": "傳送請求",
|
|
83
|
+
"apiSending": "傳送中...",
|
|
84
|
+
"apiCancel": "取消",
|
|
85
|
+
"apiRequest": "請求",
|
|
86
|
+
"apiResponse": "回應",
|
|
87
|
+
"apiResponseHeaders": "回應標頭",
|
|
88
|
+
"apiResponseBody": "回應主體",
|
|
89
|
+
"apiNoResponse": "傳送請求以檢視回應。",
|
|
90
|
+
"apiRequestFailed": "無法傳送請求。API 可能封鎖了瀏覽器請求(CORS)或無法連線;請設定 playground 代理,或在終端機中執行 cURL 範例。",
|
|
91
|
+
"apiRequestTimedOut": "請求逾時。",
|
|
92
|
+
"apiCookiesUnsupported": "Cookie 參數無法在瀏覽器中設定,因此不會傳送。",
|
|
93
|
+
"apiOptional": "選填",
|
|
94
|
+
"apiElapsed": "{ms} 毫秒",
|
|
95
|
+
"apiCredentialsStored": "憑證僅保留在此瀏覽器分頁中,只會傳送給該 API。",
|
|
96
|
+
"apiPayload": "酬載",
|
|
97
|
+
"apiSchemaProperties": "屬性",
|
|
98
|
+
"apiExample": "範例"
|
|
74
99
|
}
|