docusaurus-theme-openapi-docs 5.0.1 → 5.1.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/lib/markdown/schema.js +38 -15
- package/lib/markdown/schema.test.d.ts +1 -0
- package/lib/markdown/schema.test.js +86 -0
- package/lib/theme/ApiExplorer/ApiCodeBlock/Container/index.js +4 -2
- package/lib/theme/ApiExplorer/ApiCodeBlock/Content/String.js +9 -6
- package/lib/theme/ApiExplorer/ApiCodeBlock/Line/index.d.ts +1 -1
- package/lib/theme/ApiExplorer/ApiCodeBlock/index.d.ts +1 -1
- package/lib/theme/ApiExplorer/Authorization/index.js +9 -10
- package/lib/theme/ApiExplorer/Body/index.js +4 -5
- package/lib/theme/ApiExplorer/CodeSnippets/index.js +96 -61
- package/lib/theme/ApiExplorer/CodeSnippets/languages.js +12 -1
- package/lib/theme/ApiExplorer/CodeSnippets/languages.test.d.ts +1 -0
- package/lib/theme/ApiExplorer/CodeSnippets/languages.test.js +102 -0
- package/lib/theme/ApiExplorer/CodeTabs/index.d.ts +1 -1
- package/lib/theme/ApiExplorer/CodeTabs/index.js +6 -5
- package/lib/theme/ApiExplorer/Export/index.js +9 -2
- package/lib/theme/ApiExplorer/FormFileUpload/index.js +1 -2
- package/lib/theme/ApiExplorer/FormLabel/index.js +1 -2
- package/lib/theme/ApiExplorer/FormTextInput/index.js +1 -2
- package/lib/theme/ApiExplorer/LiveEditor/index.js +1 -2
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.js +5 -3
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.js +75 -4
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.js +1 -2
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.js +67 -4
- package/lib/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.js +65 -1
- package/lib/theme/ApiExplorer/ParamOptions/index.js +2 -3
- package/lib/theme/ApiExplorer/Request/index.js +17 -18
- package/lib/theme/ApiExplorer/Response/index.js +54 -12
- package/lib/theme/ApiExplorer/SecuritySchemes/index.js +57 -50
- package/lib/theme/ApiExplorer/Server/index.js +2 -3
- package/lib/theme/ApiItem/index.js +59 -33
- package/lib/theme/ApiTabs/index.d.ts +1 -1
- package/lib/theme/ApiTabs/index.js +7 -7
- package/lib/theme/DiscriminatorTabs/index.d.ts +1 -1
- package/lib/theme/DiscriminatorTabs/index.js +6 -5
- package/lib/theme/Example/index.js +3 -4
- package/lib/theme/MimeTabs/index.d.ts +1 -1
- package/lib/theme/MimeTabs/index.js +6 -5
- package/lib/theme/OperationTabs/index.d.ts +1 -1
- package/lib/theme/OperationTabs/index.js +6 -5
- package/lib/theme/ParamsDetails/index.js +1 -2
- package/lib/theme/ParamsItem/index.js +7 -8
- package/lib/theme/RequestSchema/index.js +57 -57
- package/lib/theme/ResponseExamples/index.js +3 -4
- package/lib/theme/ResponseSchema/index.js +26 -24
- package/lib/theme/Schema/index.js +148 -27
- package/lib/theme/SchemaExpansion/_SchemaExpansion.scss +113 -0
- package/lib/theme/SchemaExpansion/context.d.ts +24 -0
- package/lib/theme/SchemaExpansion/context.js +187 -0
- package/lib/theme/SchemaExpansion/index.d.ts +4 -0
- package/lib/theme/SchemaExpansion/index.js +314 -0
- package/lib/theme/SchemaItem/index.js +9 -10
- package/lib/theme/SchemaTabs/index.d.ts +1 -1
- package/lib/theme/SchemaTabs/index.js +6 -5
- package/lib/theme/StatusCodes/index.js +2 -4
- package/lib/theme/TabItem/index.d.ts +5 -0
- package/lib/theme/TabItem/index.js +51 -0
- package/lib/theme/TabItem/styles.module.css +3 -0
- package/lib/theme/Tabs/index.d.ts +5 -0
- package/lib/theme/Tabs/index.js +148 -0
- package/lib/theme/Tabs/styles.module.css +7 -0
- package/lib/theme/styles.scss +1 -0
- package/lib/theme/translationIds.d.ts +1 -93
- package/lib/theme/translationIds.js +0 -109
- package/lib/theme/utils/codeBlockUtils.d.ts +28 -0
- package/lib/theme/utils/codeBlockUtils.js +223 -0
- package/lib/theme/utils/reactUtils.d.ts +1 -0
- package/lib/theme/utils/reactUtils.js +23 -0
- package/lib/theme/utils/scrollUtils.d.ts +7 -0
- package/lib/theme/utils/scrollUtils.js +175 -0
- package/lib/theme/utils/tabsUtils.d.ts +47 -0
- package/lib/theme/utils/tabsUtils.js +299 -0
- package/lib/theme/utils/useCodeWordWrap.d.ts +8 -0
- package/lib/theme/utils/useCodeWordWrap.js +84 -0
- package/lib/theme/utils/useMutationObserver.d.ts +3 -0
- package/lib/theme/utils/useMutationObserver.js +34 -0
- package/package.json +4 -4
- package/src/markdown/schema.test.ts +102 -0
- package/src/markdown/schema.ts +42 -15
- package/src/theme/ApiExplorer/ApiCodeBlock/Container/index.tsx +2 -1
- package/src/theme/ApiExplorer/ApiCodeBlock/Content/String.tsx +8 -7
- package/src/theme/ApiExplorer/ApiCodeBlock/Line/index.tsx +1 -1
- package/src/theme/ApiExplorer/ApiCodeBlock/index.tsx +1 -1
- package/src/theme/ApiExplorer/Authorization/index.tsx +9 -10
- package/src/theme/ApiExplorer/Body/index.tsx +7 -5
- package/src/theme/ApiExplorer/CodeSnippets/index.tsx +103 -59
- package/src/theme/ApiExplorer/CodeSnippets/languages.test.ts +109 -0
- package/src/theme/ApiExplorer/CodeSnippets/languages.ts +13 -1
- package/src/theme/ApiExplorer/CodeTabs/index.tsx +5 -5
- package/src/theme/ApiExplorer/Export/index.tsx +6 -2
- package/src/theme/ApiExplorer/FormFileUpload/index.tsx +1 -2
- package/src/theme/ApiExplorer/FormLabel/index.tsx +1 -2
- package/src/theme/ApiExplorer/FormTextInput/index.tsx +1 -2
- package/src/theme/ApiExplorer/LiveEditor/index.tsx +1 -2
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamArrayFormItem.tsx +5 -3
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamBooleanFormItem.tsx +20 -4
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamMultiSelectFormItem.tsx +1 -2
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem.tsx +15 -4
- package/src/theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem.tsx +11 -1
- package/src/theme/ApiExplorer/ParamOptions/index.tsx +2 -3
- package/src/theme/ApiExplorer/Request/index.tsx +23 -18
- package/src/theme/ApiExplorer/Response/index.tsx +63 -9
- package/src/theme/ApiExplorer/SecuritySchemes/index.tsx +60 -52
- package/src/theme/ApiExplorer/Server/index.tsx +8 -3
- package/src/theme/ApiItem/index.tsx +43 -21
- package/src/theme/ApiTabs/index.tsx +8 -8
- package/src/theme/DiscriminatorTabs/index.tsx +6 -5
- package/src/theme/Example/index.tsx +3 -4
- package/src/theme/MimeTabs/index.tsx +9 -8
- package/src/theme/OperationTabs/index.tsx +5 -4
- package/src/theme/ParamsDetails/index.tsx +1 -2
- package/src/theme/ParamsItem/index.tsx +13 -8
- package/src/theme/RequestSchema/index.tsx +38 -40
- package/src/theme/ResponseExamples/index.tsx +3 -4
- package/src/theme/ResponseSchema/index.tsx +16 -17
- package/src/theme/Schema/index.tsx +156 -27
- package/src/theme/SchemaExpansion/_SchemaExpansion.scss +113 -0
- package/src/theme/SchemaExpansion/context.tsx +154 -0
- package/src/theme/SchemaExpansion/index.tsx +236 -0
- package/src/theme/SchemaItem/index.tsx +18 -10
- package/src/theme/SchemaTabs/index.tsx +6 -5
- package/src/theme/StatusCodes/index.tsx +2 -3
- package/src/theme/TabItem/index.tsx +61 -0
- package/src/theme/TabItem/styles.module.css +3 -0
- package/src/theme/Tabs/index.tsx +164 -0
- package/src/theme/Tabs/styles.module.css +7 -0
- package/src/theme/styles.scss +1 -0
- package/src/theme/translationIds.ts +37 -106
- package/src/theme/utils/codeBlockUtils.ts +296 -0
- package/src/theme/utils/reactUtils.ts +22 -0
- package/src/theme/utils/scrollUtils.tsx +153 -0
- package/src/theme/utils/tabsUtils.tsx +329 -0
- package/src/theme/utils/useCodeWordWrap.ts +110 -0
- package/src/theme/utils/useMutationObserver.ts +43 -0
- package/src/theme-classic.d.ts +0 -96
- package/src/types.d.ts +27 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
* Copyright (c) Palo Alto Networks
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
* ========================================================================== */
|
|
7
|
+
|
|
8
|
+
import { CodeSample, Language } from "./code-snippets-types";
|
|
9
|
+
import { mergeCodeSampleLanguage } from "./languages";
|
|
10
|
+
|
|
11
|
+
const baseLang = (
|
|
12
|
+
language: string,
|
|
13
|
+
codeSampleLanguage: Language["codeSampleLanguage"]
|
|
14
|
+
): Language => ({
|
|
15
|
+
highlight: language,
|
|
16
|
+
language,
|
|
17
|
+
codeSampleLanguage,
|
|
18
|
+
logoClass: language,
|
|
19
|
+
variant: "http",
|
|
20
|
+
variants: ["http"],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("mergeCodeSampleLanguage", () => {
|
|
24
|
+
it("returns the language unchanged when no codeSamples target it", () => {
|
|
25
|
+
const langs = [baseLang("python", "Python")];
|
|
26
|
+
const result = mergeCodeSampleLanguage(langs, []);
|
|
27
|
+
expect(result[0]).toEqual(langs[0]);
|
|
28
|
+
expect(result[0].samples).toBeUndefined();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("attaches a single sample with no label using an indexed id", () => {
|
|
32
|
+
const samples: CodeSample[] = [{ lang: "Python", source: "print('hi')" }];
|
|
33
|
+
const [py] = mergeCodeSampleLanguage(
|
|
34
|
+
[baseLang("python", "Python")],
|
|
35
|
+
samples
|
|
36
|
+
);
|
|
37
|
+
expect(py.samples).toEqual(["Python-0"]);
|
|
38
|
+
expect(py.samplesLabels).toEqual(["Python"]);
|
|
39
|
+
expect(py.samplesSources).toEqual(["print('hi')"]);
|
|
40
|
+
expect(py.sample).toBe("Python-0");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("attaches a single sample with a label using lang-label id", () => {
|
|
44
|
+
const samples: CodeSample[] = [
|
|
45
|
+
{ lang: "PHP", label: "Custom", source: "<?php" },
|
|
46
|
+
];
|
|
47
|
+
const [php] = mergeCodeSampleLanguage([baseLang("php", "PHP")], samples);
|
|
48
|
+
expect(php.samples).toEqual(["PHP-Custom"]);
|
|
49
|
+
expect(php.samplesLabels).toEqual(["Custom"]);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("produces unique ids for multiple samples sharing a lang with distinct labels (#1204)", () => {
|
|
53
|
+
const samples: CodeSample[] = [
|
|
54
|
+
{ lang: "Python", label: "KeyPair Auth", source: "a" },
|
|
55
|
+
{ lang: "Python", label: "Basic Auth", source: "b" },
|
|
56
|
+
{ lang: "Python", label: "OAuth", source: "c" },
|
|
57
|
+
];
|
|
58
|
+
const [py] = mergeCodeSampleLanguage(
|
|
59
|
+
[baseLang("python", "Python")],
|
|
60
|
+
samples
|
|
61
|
+
);
|
|
62
|
+
expect(py.samples).toEqual([
|
|
63
|
+
"Python-KeyPair Auth",
|
|
64
|
+
"Python-Basic Auth",
|
|
65
|
+
"Python-OAuth",
|
|
66
|
+
]);
|
|
67
|
+
expect(new Set(py.samples).size).toBe(3);
|
|
68
|
+
expect(py.samplesLabels).toEqual(["KeyPair Auth", "Basic Auth", "OAuth"]);
|
|
69
|
+
expect(py.samplesSources).toEqual(["a", "b", "c"]);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("produces unique indexed ids for multiple samples sharing a lang without labels", () => {
|
|
73
|
+
const samples: CodeSample[] = [
|
|
74
|
+
{ lang: "PowerShell", source: "x" },
|
|
75
|
+
{ lang: "PowerShell", source: "y" },
|
|
76
|
+
];
|
|
77
|
+
const [ps] = mergeCodeSampleLanguage(
|
|
78
|
+
[baseLang("powershell", "PowerShell")],
|
|
79
|
+
samples
|
|
80
|
+
);
|
|
81
|
+
expect(ps.samples).toEqual(["PowerShell-0", "PowerShell-1"]);
|
|
82
|
+
expect(new Set(ps.samples).size).toBe(2);
|
|
83
|
+
expect(ps.samplesLabels).toEqual(["PowerShell", "PowerShell"]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("defensively suffixes ids when lang+label collides", () => {
|
|
87
|
+
const samples: CodeSample[] = [
|
|
88
|
+
{ lang: "Java", label: "Auth", source: "a" },
|
|
89
|
+
{ lang: "Java", label: "Auth", source: "b" },
|
|
90
|
+
];
|
|
91
|
+
const [java] = mergeCodeSampleLanguage([baseLang("java", "Java")], samples);
|
|
92
|
+
expect(java.samples).toEqual(["Java-Auth", "Java-Auth-1"]);
|
|
93
|
+
expect(new Set(java.samples).size).toBe(2);
|
|
94
|
+
expect(java.samplesLabels).toEqual(["Auth", "Auth"]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("filters codeSamples by codeSampleLanguage and leaves other languages alone", () => {
|
|
98
|
+
const samples: CodeSample[] = [
|
|
99
|
+
{ lang: "Python", label: "A", source: "a" },
|
|
100
|
+
{ lang: "Java", label: "B", source: "b" },
|
|
101
|
+
];
|
|
102
|
+
const result = mergeCodeSampleLanguage(
|
|
103
|
+
[baseLang("python", "Python"), baseLang("php", "PHP")],
|
|
104
|
+
samples
|
|
105
|
+
);
|
|
106
|
+
expect(result[0].samples).toEqual(["Python-A"]);
|
|
107
|
+
expect(result[1].samples).toBeUndefined();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -22,12 +22,24 @@ export function mergeCodeSampleLanguage(
|
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
if (languageCodeSamples.length) {
|
|
25
|
-
const samples = languageCodeSamples.map(({ lang }) => lang);
|
|
26
25
|
const samplesLabels = languageCodeSamples.map(
|
|
27
26
|
({ label, lang }) => label || lang
|
|
28
27
|
);
|
|
29
28
|
const samplesSources = languageCodeSamples.map(({ source }) => source);
|
|
30
29
|
|
|
30
|
+
// Build a unique id per sample for use as the inner Tab's `value`.
|
|
31
|
+
// Prefer `${lang}-${label}`; fall back to `${lang}-${index}` when no
|
|
32
|
+
// label is provided. Defensively suffix with `-${index}` on collision
|
|
33
|
+
// so duplicate-label specs render two visually identical tabs instead
|
|
34
|
+
// of crashing Docusaurus's unique-value check.
|
|
35
|
+
const seen = new Set<string>();
|
|
36
|
+
const samples = languageCodeSamples.map((cs, i) => {
|
|
37
|
+
const base = cs.label ? `${cs.lang}-${cs.label}` : `${cs.lang}-${i}`;
|
|
38
|
+
const id = seen.has(base) ? `${base}-${i}` : base;
|
|
39
|
+
seen.add(id);
|
|
40
|
+
return id;
|
|
41
|
+
});
|
|
42
|
+
|
|
31
43
|
return {
|
|
32
44
|
...language,
|
|
33
45
|
sample: samples[0],
|
|
@@ -7,17 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
import React, { cloneElement, ReactElement, useEffect, useRef } from "react";
|
|
9
9
|
|
|
10
|
+
import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
11
|
+
import clsx from "clsx";
|
|
12
|
+
|
|
13
|
+
import { useScrollPositionBlocker } from "@theme/utils/scrollUtils";
|
|
10
14
|
import {
|
|
11
15
|
sanitizeTabsChildren,
|
|
12
16
|
type TabItemProps,
|
|
13
17
|
type TabProps,
|
|
14
18
|
TabsProvider,
|
|
15
|
-
useScrollPositionBlocker,
|
|
16
19
|
useTabsContextValue,
|
|
17
|
-
} from "@
|
|
18
|
-
import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
19
|
-
import clsx from "clsx";
|
|
20
|
-
|
|
20
|
+
} from "@theme/utils/tabsUtils";
|
|
21
21
|
import { Language } from "../CodeSnippets/code-snippets-types";
|
|
22
22
|
|
|
23
23
|
export interface Props {
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
|
|
10
|
+
import { translate } from "@docusaurus/Translate";
|
|
10
11
|
import fileSaver from "file-saver";
|
|
11
12
|
|
|
12
13
|
const saveFile = (url: string) => {
|
|
@@ -24,7 +25,7 @@ function Export({ url, proxy }: any) {
|
|
|
24
25
|
className="dropdown dropdown--hoverable dropdown--right"
|
|
25
26
|
>
|
|
26
27
|
<button className="export-button button button--sm button--secondary">
|
|
27
|
-
Export
|
|
28
|
+
{translate({ id: "theme.openapi.export.button", message: "Export" })}
|
|
28
29
|
</button>
|
|
29
30
|
<ul className="export-dropdown dropdown__menu">
|
|
30
31
|
<li>
|
|
@@ -36,7 +37,10 @@ function Export({ url, proxy }: any) {
|
|
|
36
37
|
className="dropdown__link"
|
|
37
38
|
href={`${url}`}
|
|
38
39
|
>
|
|
39
|
-
|
|
40
|
+
{translate({
|
|
41
|
+
id: "theme.openapi.export.openapiSpec",
|
|
42
|
+
message: "OpenAPI Spec",
|
|
43
|
+
})}
|
|
40
44
|
</a>
|
|
41
45
|
</li>
|
|
42
46
|
</ul>
|
|
@@ -9,7 +9,6 @@ import React, { useState } from "react";
|
|
|
9
9
|
|
|
10
10
|
import { translate } from "@docusaurus/Translate";
|
|
11
11
|
import FloatingButton from "@theme/ApiExplorer/FloatingButton";
|
|
12
|
-
import { OPENAPI_FORM_FILE_UPLOAD } from "@theme/translationIds";
|
|
13
12
|
import MagicDropzone from "react-magic-dropzone";
|
|
14
13
|
|
|
15
14
|
type PreviewFile = { preview: string } & File;
|
|
@@ -105,7 +104,7 @@ function FormFileUpload({ placeholder, onChange }: Props) {
|
|
|
105
104
|
}}
|
|
106
105
|
>
|
|
107
106
|
{translate({
|
|
108
|
-
id:
|
|
107
|
+
id: "theme.openapi.formFileUpload.clearButton",
|
|
109
108
|
message: "Clear",
|
|
110
109
|
})}
|
|
111
110
|
</button>
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
import React from "react";
|
|
9
9
|
|
|
10
10
|
import { translate } from "@docusaurus/Translate";
|
|
11
|
-
import { OPENAPI_SCHEMA_ITEM } from "@theme/translationIds";
|
|
12
11
|
|
|
13
12
|
export interface Props {
|
|
14
13
|
htmlFor?: string;
|
|
@@ -31,7 +30,7 @@ function FormLabel({ htmlFor, label, type, required }: Props) {
|
|
|
31
30
|
{required && (
|
|
32
31
|
<span className="openapi-schema__required">
|
|
33
32
|
{translate({
|
|
34
|
-
id:
|
|
33
|
+
id: "theme.openapi.schemaItem.required",
|
|
35
34
|
message: "required",
|
|
36
35
|
})}
|
|
37
36
|
</span>
|
|
@@ -11,7 +11,6 @@ import React, { useId } from "react";
|
|
|
11
11
|
import { translate } from "@docusaurus/Translate";
|
|
12
12
|
import { ErrorMessage } from "@hookform/error-message";
|
|
13
13
|
import FormLabel from "@theme/ApiExplorer/FormLabel";
|
|
14
|
-
import { OPENAPI_FORM } from "@theme/translationIds";
|
|
15
14
|
import clsx from "clsx";
|
|
16
15
|
import { useFormContext } from "react-hook-form";
|
|
17
16
|
|
|
@@ -59,7 +58,7 @@ function FormTextInput({
|
|
|
59
58
|
{...register(paramName, {
|
|
60
59
|
required: isRequired
|
|
61
60
|
? translate({
|
|
62
|
-
id:
|
|
61
|
+
id: "theme.openapi.form.fieldRequired",
|
|
63
62
|
message: "This field is required",
|
|
64
63
|
})
|
|
65
64
|
: false,
|
|
@@ -11,7 +11,6 @@ import { usePrismTheme } from "@docusaurus/theme-common";
|
|
|
11
11
|
import { translate } from "@docusaurus/Translate";
|
|
12
12
|
import useIsBrowser from "@docusaurus/useIsBrowser";
|
|
13
13
|
import { ErrorMessage } from "@hookform/error-message";
|
|
14
|
-
import { OPENAPI_FORM } from "@theme/translationIds";
|
|
15
14
|
import clsx from "clsx";
|
|
16
15
|
import { Controller, useFormContext } from "react-hook-form";
|
|
17
16
|
import { LiveProvider, LiveEditor, withLive } from "react-live";
|
|
@@ -89,7 +88,7 @@ function App({
|
|
|
89
88
|
required:
|
|
90
89
|
isRequired && !code
|
|
91
90
|
? translate({
|
|
92
|
-
id:
|
|
91
|
+
id: "theme.openapi.form.fieldRequired",
|
|
93
92
|
message: "This field is required",
|
|
94
93
|
})
|
|
95
94
|
: false,
|
|
@@ -15,7 +15,6 @@ import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
|
15
15
|
import FormTextInput from "@theme/ApiExplorer/FormTextInput";
|
|
16
16
|
import { Param, setParam } from "@theme/ApiExplorer/ParamOptions/slice";
|
|
17
17
|
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
18
|
-
import { OPENAPI_FORM } from "@theme/translationIds";
|
|
19
18
|
import { Controller, useFormContext } from "react-hook-form";
|
|
20
19
|
|
|
21
20
|
export interface ParamProps {
|
|
@@ -138,7 +137,7 @@ export default function ParamArrayFormItem({
|
|
|
138
137
|
rules={{
|
|
139
138
|
required: param.required
|
|
140
139
|
? translate({
|
|
141
|
-
id:
|
|
140
|
+
id: "theme.openapi.form.fieldRequired",
|
|
142
141
|
message: "This field is required",
|
|
143
142
|
})
|
|
144
143
|
: false,
|
|
@@ -177,7 +176,10 @@ export default function ParamArrayFormItem({
|
|
|
177
176
|
className="openapi-explorer__thin-btn"
|
|
178
177
|
onClick={handleAddItem}
|
|
179
178
|
>
|
|
180
|
-
|
|
179
|
+
{translate({
|
|
180
|
+
id: "theme.openapi.paramArray.addItem",
|
|
181
|
+
message: "Add item",
|
|
182
|
+
})}
|
|
181
183
|
</button>
|
|
182
184
|
</>
|
|
183
185
|
)}
|
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import React from "react";
|
|
8
|
+
import React, { useEffect } from "react";
|
|
9
9
|
|
|
10
10
|
import { translate } from "@docusaurus/Translate";
|
|
11
11
|
import { ErrorMessage } from "@hookform/error-message";
|
|
12
12
|
import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
13
13
|
import { Param, setParam } from "@theme/ApiExplorer/ParamOptions/slice";
|
|
14
14
|
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
15
|
-
import { OPENAPI_FORM } from "@theme/translationIds";
|
|
16
15
|
import { Controller, useFormContext } from "react-hook-form";
|
|
17
16
|
|
|
18
17
|
export interface ParamProps {
|
|
@@ -33,10 +32,26 @@ export default function ParamBooleanFormItem({
|
|
|
33
32
|
const {
|
|
34
33
|
control,
|
|
35
34
|
formState: { errors },
|
|
35
|
+
setValue,
|
|
36
36
|
} = useFormContext();
|
|
37
37
|
|
|
38
38
|
const showErrorMessage = errors?.paramBoolean;
|
|
39
39
|
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (param.value === undefined) return;
|
|
42
|
+
const initial =
|
|
43
|
+
typeof param.value === "boolean" ? String(param.value) : param.value;
|
|
44
|
+
if (initial === "true" || initial === "false") {
|
|
45
|
+
setValue("paramBoolean", initial);
|
|
46
|
+
// Boolean defaults arrive in redux as actual booleans; normalize to the
|
|
47
|
+
// string form the rest of the form uses.
|
|
48
|
+
if (typeof param.value === "boolean") {
|
|
49
|
+
dispatch(setParam({ ...param, value: initial }));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
40
55
|
return (
|
|
41
56
|
<>
|
|
42
57
|
<Controller
|
|
@@ -44,17 +59,18 @@ export default function ParamBooleanFormItem({
|
|
|
44
59
|
rules={{
|
|
45
60
|
required: param.required
|
|
46
61
|
? translate({
|
|
47
|
-
id:
|
|
62
|
+
id: "theme.openapi.form.fieldRequired",
|
|
48
63
|
message: "This field is required",
|
|
49
64
|
})
|
|
50
65
|
: false,
|
|
51
66
|
}}
|
|
52
67
|
name="paramBoolean"
|
|
53
|
-
render={({ field: { onChange } }) => (
|
|
68
|
+
render={({ field: { onChange, value } }) => (
|
|
54
69
|
<FormSelect
|
|
55
70
|
label={label}
|
|
56
71
|
type={type}
|
|
57
72
|
required={required}
|
|
73
|
+
value={value ?? "---"}
|
|
58
74
|
options={["---", "true", "false"]}
|
|
59
75
|
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
60
76
|
const val = e.target.value;
|
|
@@ -13,7 +13,6 @@ import FormMultiSelect from "@theme/ApiExplorer/FormMultiSelect";
|
|
|
13
13
|
import { getSchemaEnum } from "@theme/ApiExplorer/ParamOptions";
|
|
14
14
|
import { Param, setParam } from "@theme/ApiExplorer/ParamOptions/slice";
|
|
15
15
|
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
|
|
16
|
-
import { OPENAPI_FORM } from "@theme/translationIds";
|
|
17
16
|
import { Controller, useFormContext } from "react-hook-form";
|
|
18
17
|
|
|
19
18
|
export interface ParamProps {
|
|
@@ -75,7 +74,7 @@ export default function ParamMultiSelectFormItem({
|
|
|
75
74
|
rules={{
|
|
76
75
|
required: param.required
|
|
77
76
|
? translate({
|
|
78
|
-
id:
|
|
77
|
+
id: "theme.openapi.form.fieldRequired",
|
|
79
78
|
message: "This field is required",
|
|
80
79
|
})
|
|
81
80
|
: false,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import React from "react";
|
|
8
|
+
import React, { useEffect } from "react";
|
|
9
9
|
|
|
10
10
|
import { translate } from "@docusaurus/Translate";
|
|
11
11
|
import { ErrorMessage } from "@hookform/error-message";
|
|
@@ -13,7 +13,6 @@ import FormSelect from "@theme/ApiExplorer/FormSelect";
|
|
|
13
13
|
import { getSchemaEnum } from "@theme/ApiExplorer/ParamOptions";
|
|
14
14
|
import { Param, setParam } from "@theme/ApiExplorer/ParamOptions/slice";
|
|
15
15
|
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
16
|
-
import { OPENAPI_FORM } from "@theme/translationIds";
|
|
17
16
|
import { Controller, useFormContext } from "react-hook-form";
|
|
18
17
|
|
|
19
18
|
export interface ParamProps {
|
|
@@ -32,6 +31,7 @@ export default function ParamSelectFormItem({
|
|
|
32
31
|
const {
|
|
33
32
|
control,
|
|
34
33
|
formState: { errors },
|
|
34
|
+
setValue,
|
|
35
35
|
} = useFormContext();
|
|
36
36
|
|
|
37
37
|
const showErrorMessage = errors?.paramSelect;
|
|
@@ -40,6 +40,16 @@ export default function ParamSelectFormItem({
|
|
|
40
40
|
|
|
41
41
|
const options = getSchemaEnum(param.schema) ?? [];
|
|
42
42
|
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (
|
|
45
|
+
typeof param.value === "string" &&
|
|
46
|
+
(options as string[]).includes(param.value)
|
|
47
|
+
) {
|
|
48
|
+
setValue("paramSelect", param.value);
|
|
49
|
+
}
|
|
50
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
43
53
|
return (
|
|
44
54
|
<>
|
|
45
55
|
<Controller
|
|
@@ -47,17 +57,18 @@ export default function ParamSelectFormItem({
|
|
|
47
57
|
rules={{
|
|
48
58
|
required: param.required
|
|
49
59
|
? translate({
|
|
50
|
-
id:
|
|
60
|
+
id: "theme.openapi.form.fieldRequired",
|
|
51
61
|
message: "This field is required",
|
|
52
62
|
})
|
|
53
63
|
: false,
|
|
54
64
|
}}
|
|
55
65
|
name="paramSelect"
|
|
56
|
-
render={({ field: { onChange } }) => (
|
|
66
|
+
render={({ field: { onChange, value } }) => (
|
|
57
67
|
<FormSelect
|
|
58
68
|
label={label}
|
|
59
69
|
type={type}
|
|
60
70
|
required={required}
|
|
71
|
+
value={value ?? "---"}
|
|
61
72
|
options={["---", ...(options as string[])]}
|
|
62
73
|
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
63
74
|
const val = e.target.value;
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import React from "react";
|
|
8
|
+
import React, { useEffect } from "react";
|
|
9
9
|
|
|
10
10
|
import FormTextInput from "@theme/ApiExplorer/FormTextInput";
|
|
11
11
|
import { Param, setParam } from "@theme/ApiExplorer/ParamOptions/slice";
|
|
12
12
|
import { useTypedDispatch } from "@theme/ApiItem/hooks";
|
|
13
|
+
import { useFormContext } from "react-hook-form";
|
|
13
14
|
|
|
14
15
|
export interface ParamProps {
|
|
15
16
|
param: Param;
|
|
@@ -25,6 +26,15 @@ export default function ParamTextFormItem({
|
|
|
25
26
|
required,
|
|
26
27
|
}: ParamProps) {
|
|
27
28
|
const dispatch = useTypedDispatch();
|
|
29
|
+
const { setValue } = useFormContext();
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (param.value !== undefined && !Array.isArray(param.value)) {
|
|
33
|
+
setValue(param.name, param.value);
|
|
34
|
+
}
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
}, []);
|
|
37
|
+
|
|
28
38
|
return (
|
|
29
39
|
<FormTextInput
|
|
30
40
|
label={label}
|
|
@@ -15,7 +15,6 @@ import ParamMultiSelectFormItem from "@theme/ApiExplorer/ParamOptions/ParamFormI
|
|
|
15
15
|
import ParamSelectFormItem from "@theme/ApiExplorer/ParamOptions/ParamFormItems/ParamSelectFormItem";
|
|
16
16
|
import ParamTextFormItem from "@theme/ApiExplorer/ParamOptions/ParamFormItems/ParamTextFormItem";
|
|
17
17
|
import { useTypedSelector } from "@theme/ApiItem/hooks";
|
|
18
|
-
import { OPENAPI_PARAM_OPTIONS } from "@theme/translationIds";
|
|
19
18
|
|
|
20
19
|
import { Param } from "./slice";
|
|
21
20
|
|
|
@@ -207,11 +206,11 @@ function ParamOptions() {
|
|
|
207
206
|
</span>
|
|
208
207
|
{showOptional
|
|
209
208
|
? translate({
|
|
210
|
-
id:
|
|
209
|
+
id: "theme.openapi.paramOptions.hideOptional",
|
|
211
210
|
message: "Hide optional parameters",
|
|
212
211
|
})
|
|
213
212
|
: translate({
|
|
214
|
-
id:
|
|
213
|
+
id: "theme.openapi.paramOptions.showOptional",
|
|
215
214
|
message: "Show optional parameters",
|
|
216
215
|
})}
|
|
217
216
|
</button>
|
|
@@ -16,6 +16,7 @@ import Authorization from "@theme/ApiExplorer/Authorization";
|
|
|
16
16
|
import Body from "@theme/ApiExplorer/Body";
|
|
17
17
|
import buildPostmanRequest from "@theme/ApiExplorer/buildPostmanRequest";
|
|
18
18
|
import ContentType from "@theme/ApiExplorer/ContentType";
|
|
19
|
+
import { useResolvedEncoding } from "@theme/ApiExplorer/EncodingSelection/useResolvedEncoding";
|
|
19
20
|
import ParamOptions from "@theme/ApiExplorer/ParamOptions";
|
|
20
21
|
import {
|
|
21
22
|
setResponse,
|
|
@@ -25,9 +26,7 @@ import {
|
|
|
25
26
|
clearHeaders,
|
|
26
27
|
} from "@theme/ApiExplorer/Response/slice";
|
|
27
28
|
import Server from "@theme/ApiExplorer/Server";
|
|
28
|
-
import { useResolvedEncoding } from "@theme/ApiExplorer/EncodingSelection/useResolvedEncoding";
|
|
29
29
|
import { useTypedDispatch, useTypedSelector } from "@theme/ApiItem/hooks";
|
|
30
|
-
import { OPENAPI_REQUEST } from "@theme/translationIds";
|
|
31
30
|
import type { ParameterObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
32
31
|
import type { ApiItem } from "docusaurus-plugin-openapi-docs/src/types";
|
|
33
32
|
import type { ThemeConfig } from "docusaurus-theme-openapi-docs/src/types";
|
|
@@ -137,26 +136,26 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
137
136
|
switch (errorType) {
|
|
138
137
|
case "timeout":
|
|
139
138
|
return translate({
|
|
140
|
-
id:
|
|
139
|
+
id: "theme.openapi.request.error.timeout",
|
|
141
140
|
message:
|
|
142
141
|
"The request timed out waiting for the server to respond. Please try again. If the issue persists, try using a different client (e.g., curl) with a longer timeout.",
|
|
143
142
|
});
|
|
144
143
|
case "network":
|
|
145
144
|
return translate({
|
|
146
|
-
id:
|
|
145
|
+
id: "theme.openapi.request.error.network",
|
|
147
146
|
message:
|
|
148
147
|
"Unable to reach the server. Please check your network connection and verify the server URL is correct. If the server is running, this may be a CORS issue.",
|
|
149
148
|
});
|
|
150
149
|
case "cors":
|
|
151
150
|
return translate({
|
|
152
|
-
id:
|
|
151
|
+
id: "theme.openapi.request.error.cors",
|
|
153
152
|
message:
|
|
154
153
|
"The request was blocked, possibly due to CORS restrictions. Ensure the server allows requests from this origin, or try using a proxy.",
|
|
155
154
|
});
|
|
156
155
|
case "unknown":
|
|
157
156
|
default:
|
|
158
157
|
return translate({
|
|
159
|
-
id:
|
|
158
|
+
id: "theme.openapi.request.error.unknown",
|
|
160
159
|
message:
|
|
161
160
|
"An unexpected error occurred while making the request. Please try again.",
|
|
162
161
|
});
|
|
@@ -167,7 +166,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
167
166
|
dispatch(
|
|
168
167
|
setResponse(
|
|
169
168
|
translate({
|
|
170
|
-
id:
|
|
169
|
+
id: "theme.openapi.request.fetchingMessage",
|
|
171
170
|
message: "Fetching...",
|
|
172
171
|
})
|
|
173
172
|
)
|
|
@@ -195,7 +194,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
195
194
|
errorMessage = getErrorMessage(e.type);
|
|
196
195
|
} else {
|
|
197
196
|
errorMessage = translate({
|
|
198
|
-
id:
|
|
197
|
+
id: "theme.openapi.request.connectionFailed",
|
|
199
198
|
message: "Connection failed",
|
|
200
199
|
});
|
|
201
200
|
}
|
|
@@ -253,7 +252,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
253
252
|
<div className="openapi-explorer__request-header-container">
|
|
254
253
|
<span className="openapi-explorer__request-title">
|
|
255
254
|
{translate({
|
|
256
|
-
id:
|
|
255
|
+
id: "theme.openapi.request.title",
|
|
257
256
|
message: "Request",
|
|
258
257
|
})}
|
|
259
258
|
</span>
|
|
@@ -264,7 +263,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
264
263
|
onClick={collapseAllDetails}
|
|
265
264
|
>
|
|
266
265
|
{translate({
|
|
267
|
-
id:
|
|
266
|
+
id: "theme.openapi.request.collapseAll",
|
|
268
267
|
message: "Collapse all",
|
|
269
268
|
})}
|
|
270
269
|
</button>
|
|
@@ -275,7 +274,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
275
274
|
onClick={expandAllDetails}
|
|
276
275
|
>
|
|
277
276
|
{translate({
|
|
278
|
-
id:
|
|
277
|
+
id: "theme.openapi.request.expandAll",
|
|
279
278
|
message: "Expand all",
|
|
280
279
|
})}
|
|
281
280
|
</button>
|
|
@@ -296,7 +295,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
296
295
|
}}
|
|
297
296
|
>
|
|
298
297
|
{translate({
|
|
299
|
-
id:
|
|
298
|
+
id: "theme.openapi.request.baseUrl.title",
|
|
300
299
|
message: "Base URL",
|
|
301
300
|
})}
|
|
302
301
|
</summary>
|
|
@@ -315,7 +314,10 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
315
314
|
setExpandAuth(!expandAuth);
|
|
316
315
|
}}
|
|
317
316
|
>
|
|
318
|
-
{translate({
|
|
317
|
+
{translate({
|
|
318
|
+
id: "theme.openapi.request.auth.title",
|
|
319
|
+
message: "Auth",
|
|
320
|
+
})}
|
|
319
321
|
</summary>
|
|
320
322
|
<Authorization />
|
|
321
323
|
</details>
|
|
@@ -335,7 +337,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
335
337
|
}}
|
|
336
338
|
>
|
|
337
339
|
{translate({
|
|
338
|
-
id:
|
|
340
|
+
id: "theme.openapi.request.parameters.title",
|
|
339
341
|
message: "Parameters",
|
|
340
342
|
})}
|
|
341
343
|
</summary>
|
|
@@ -354,12 +356,15 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
354
356
|
setExpandBody(!expandBody);
|
|
355
357
|
}}
|
|
356
358
|
>
|
|
357
|
-
{translate({
|
|
359
|
+
{translate({
|
|
360
|
+
id: "theme.openapi.request.body.title",
|
|
361
|
+
message: "Body",
|
|
362
|
+
})}
|
|
358
363
|
{requestBodyRequired && (
|
|
359
364
|
<span className="openapi-schema__required">
|
|
360
365
|
|
|
361
366
|
{translate({
|
|
362
|
-
id:
|
|
367
|
+
id: "theme.openapi.request.requiredLabel",
|
|
363
368
|
message: "required",
|
|
364
369
|
})}
|
|
365
370
|
</span>
|
|
@@ -388,7 +393,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
388
393
|
}}
|
|
389
394
|
>
|
|
390
395
|
{translate({
|
|
391
|
-
id:
|
|
396
|
+
id: "theme.openapi.request.accept.title",
|
|
392
397
|
message: "Accept",
|
|
393
398
|
})}
|
|
394
399
|
</summary>
|
|
@@ -398,7 +403,7 @@ function Request({ item }: { item: ApiItem }) {
|
|
|
398
403
|
{showRequestButton && item.method !== "event" && (
|
|
399
404
|
<button className="openapi-explorer__request-btn" type="submit">
|
|
400
405
|
{translate({
|
|
401
|
-
id:
|
|
406
|
+
id: "theme.openapi.request.sendButton",
|
|
402
407
|
message: "Send API Request",
|
|
403
408
|
})}
|
|
404
409
|
</button>
|