@gitbook/react-openapi 1.5.1 → 1.5.3

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.
Files changed (87) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/InteractiveSection.js +59 -0
  3. package/dist/Markdown.js +10 -0
  4. package/dist/OpenAPICodeSample.js +219 -0
  5. package/dist/OpenAPICodeSampleInteractive.js +62 -0
  6. package/dist/OpenAPICodeSampleSelector.js +45 -0
  7. package/dist/OpenAPICopyButton.js +44 -0
  8. package/dist/OpenAPIDisclosure.js +28 -0
  9. package/dist/OpenAPIDisclosureGroup.js +89 -0
  10. package/dist/OpenAPIExample.js +41 -0
  11. package/dist/OpenAPIMediaType.js +58 -0
  12. package/dist/OpenAPIOperation.d.ts +15 -0
  13. package/dist/OpenAPIOperation.js +30 -0
  14. package/dist/OpenAPIOperationContext.d.ts +20 -0
  15. package/dist/OpenAPIOperationContext.js +30 -0
  16. package/dist/OpenAPIPath.js +25 -0
  17. package/dist/OpenAPIPathItem.js +22 -0
  18. package/dist/OpenAPIPathMultipleServers.js +43 -0
  19. package/dist/OpenAPIPrefillContextProvider.d.ts +26 -0
  20. package/dist/OpenAPIPrefillContextProvider.js +25 -0
  21. package/dist/OpenAPIRequestBody.js +28 -0
  22. package/dist/OpenAPIRequestBodyHeaderType.js +23 -0
  23. package/dist/OpenAPIRequiredScopes.js +67 -0
  24. package/dist/OpenAPIResponse.js +39 -0
  25. package/dist/OpenAPIResponseExample.js +75 -0
  26. package/dist/OpenAPIResponseExampleContent.js +61 -0
  27. package/dist/OpenAPIResponses.js +61 -0
  28. package/dist/OpenAPISchema.js +373 -0
  29. package/dist/OpenAPISchemaName.js +45 -0
  30. package/dist/OpenAPISchemaServer.js +13 -0
  31. package/dist/OpenAPISecurities.js +98 -0
  32. package/dist/OpenAPISelect.js +45 -0
  33. package/dist/OpenAPISpec.js +73 -0
  34. package/dist/OpenAPITooltip.js +23 -0
  35. package/dist/OpenAPIWebhook.d.ts +15 -0
  36. package/dist/OpenAPIWebhook.js +28 -0
  37. package/dist/OpenAPIWebhookExample.js +40 -0
  38. package/dist/ScalarApiButton.js +90 -0
  39. package/dist/StaticSection.js +37 -0
  40. package/dist/code-samples.js +305 -0
  41. package/dist/common/OpenAPIColumnSpec.js +23 -0
  42. package/dist/common/OpenAPIOperationDescription.js +18 -0
  43. package/dist/common/OpenAPIStability.js +17 -0
  44. package/dist/common/OpenAPISummary.js +27 -0
  45. package/dist/contentTypeChecks.js +34 -0
  46. package/dist/context.d.ts +74 -0
  47. package/dist/context.js +29 -0
  48. package/dist/decycle.js +41 -0
  49. package/dist/dereference.js +24 -0
  50. package/dist/formatPath.js +25 -0
  51. package/dist/generateSchemaExample.js +198 -0
  52. package/dist/getDisclosureLabel.js +17 -0
  53. package/dist/getOrCreateDisclosureStoreByKey.js +31 -0
  54. package/dist/getOrCreateStoreByKey.js +22 -0
  55. package/dist/index.d.ts +11 -662
  56. package/dist/index.js +9 -3871
  57. package/dist/json2xml.js +12 -0
  58. package/dist/resolveOpenAPIOperation.d.ts +15 -0
  59. package/dist/resolveOpenAPIOperation.js +105 -0
  60. package/dist/resolveOpenAPIWebhook.d.ts +15 -0
  61. package/dist/resolveOpenAPIWebhook.js +52 -0
  62. package/dist/schemas/OpenAPISchemaItem.js +26 -0
  63. package/dist/schemas/OpenAPISchemas.d.ts +19 -0
  64. package/dist/schemas/OpenAPISchemas.js +57 -0
  65. package/dist/schemas/resolveOpenAPISchemas.d.ts +15 -0
  66. package/dist/schemas/resolveOpenAPISchemas.js +17 -0
  67. package/dist/stringifyOpenAPI.js +14 -0
  68. package/dist/translate.js +43 -0
  69. package/dist/translations/de.js +50 -0
  70. package/dist/translations/en.d.ts +49 -0
  71. package/dist/translations/en.js +50 -0
  72. package/dist/translations/es.js +50 -0
  73. package/dist/translations/fr.js +50 -0
  74. package/dist/translations/index.d.ts +426 -0
  75. package/dist/translations/index.js +31 -0
  76. package/dist/translations/ja.js +50 -0
  77. package/dist/translations/nl.js +50 -0
  78. package/dist/translations/no.js +50 -0
  79. package/dist/translations/pt-br.js +50 -0
  80. package/dist/translations/types.d.ts +7 -0
  81. package/dist/translations/zh.js +50 -0
  82. package/dist/types.d.ts +38 -0
  83. package/dist/util/example.js +84 -0
  84. package/dist/util/server.js +38 -0
  85. package/dist/util/tryit-prefill.js +143 -0
  86. package/dist/utils.js +163 -0
  87. package/package.json +28 -12
@@ -0,0 +1,15 @@
1
+ import { OpenAPIContextInput } from "./context.js";
2
+ import { OpenAPIWebhookData } from "./types.js";
3
+ import * as react0 from "react";
4
+
5
+ //#region src/OpenAPIWebhook.d.ts
6
+ /**
7
+ * Display an interactive OpenAPI webhook.
8
+ */
9
+ declare function OpenAPIWebhook(props: {
10
+ className?: string;
11
+ data: OpenAPIWebhookData;
12
+ context: OpenAPIContextInput;
13
+ }): react0.JSX.Element;
14
+ //#endregion
15
+ export { OpenAPIWebhook };
@@ -0,0 +1,28 @@
1
+ import { resolveOpenAPIContext } from "./context.js";
2
+ import { OpenAPIColumnSpec } from "./common/OpenAPIColumnSpec.js";
3
+ import { OpenAPISummary } from "./common/OpenAPISummary.js";
4
+ import { OpenAPIWebhookExample } from "./OpenAPIWebhookExample.js";
5
+ import clsx from "classnames";
6
+
7
+ //#region src/OpenAPIWebhook.tsx
8
+ /**
9
+ * Display an interactive OpenAPI webhook.
10
+ */
11
+ function OpenAPIWebhook(props) {
12
+ const { className, data, context: contextInput } = props;
13
+ const context = resolveOpenAPIContext(contextInput);
14
+ return <div className={clsx("openapi-webhook", className)}>
15
+ <OpenAPISummary data={data} context={context} />
16
+ <div className="openapi-columns">
17
+ <OpenAPIColumnSpec data={data} context={context} />
18
+ <div className="openapi-column-preview">
19
+ <div className="openapi-column-preview-body">
20
+ <OpenAPIWebhookExample data={data} context={context} />
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </div>;
25
+ }
26
+
27
+ //#endregion
28
+ export { OpenAPIWebhook };
@@ -0,0 +1,40 @@
1
+ import { OpenAPIEmptyExample } from "./OpenAPIExample.js";
2
+ import { createStateKey } from "./utils.js";
3
+ import { getOpenAPIClientContext } from "./context.js";
4
+ import { getExamples } from "./util/example.js";
5
+ import { OpenAPIMediaTypeContent } from "./OpenAPIMediaType.js";
6
+
7
+ //#region src/OpenAPIWebhookExample.tsx
8
+ function OpenAPIWebhookExample(props) {
9
+ const { data, context } = props;
10
+ const { operation } = data;
11
+ const items = (() => {
12
+ if (!operation.requestBody) return [];
13
+ return Object.entries(operation.requestBody.content).map(([key, value]) => {
14
+ if (!value?.schema) return {
15
+ key,
16
+ label: key,
17
+ body: <OpenAPIEmptyExample context={context} />
18
+ };
19
+ return {
20
+ key,
21
+ label: key,
22
+ body: <></>,
23
+ examples: getExamples({
24
+ mediaTypeObject: value,
25
+ mediaType: key,
26
+ context
27
+ })
28
+ };
29
+ });
30
+ })();
31
+ return <div className="openapi-panel">
32
+ <h4 className="openapi-panel-heading">Payload</h4>
33
+ <div className="openapi-panel-body">
34
+ <OpenAPIMediaTypeContent selectIcon={context.icons.chevronDown} stateKey={createStateKey("request-body-media-type", context.blockKey)} items={items} context={getOpenAPIClientContext(context)} />
35
+ </div>
36
+ </div>;
37
+ }
38
+
39
+ //#endregion
40
+ export { OpenAPIWebhookExample };
@@ -0,0 +1,90 @@
1
+ 'use client';
2
+
3
+
4
+ import { t } from "./translate.js";
5
+ import { useOpenAPIOperationContext } from "./OpenAPIOperationContext.js";
6
+ import { useOpenAPIPrefillContext } from "./OpenAPIPrefillContextProvider.js";
7
+ import { resolveTryItPrefillForOperation } from "./util/tryit-prefill.js";
8
+ import { Suspense, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
9
+ import { ApiClientModalProvider, useApiClientModal } from "@scalar/api-client-react";
10
+ import { createPortal } from "react-dom";
11
+
12
+ //#region src/ScalarApiButton.tsx
13
+ /**
14
+ * Button which launches the Scalar API Client
15
+ */
16
+ function ScalarApiButton(props) {
17
+ const { method, path, securities, servers, specUrl, context } = props;
18
+ const [isOpen, setIsOpen] = useState(false);
19
+ const controllerRef = useRef(null);
20
+ return <div className="scalar scalar-activate">
21
+ <button className="scalar-activate-button button" onClick={() => {
22
+ controllerRef.current?.openClient?.();
23
+ setIsOpen(true);
24
+ }}>
25
+ {t(context.translation, "test_it")}
26
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 12" fill="currentColor">
27
+ <path stroke="currentColor" strokeWidth="1.5" d="M1 10.05V1.43c0-.2.2-.31.37-.22l7.26 4.08c.17.1.17.33.01.43l-7.26 4.54a.25.25 0 0 1-.38-.21Z" />
28
+ </svg>
29
+ </button>
30
+
31
+ {isOpen && createPortal(<Suspense fallback={null}>
32
+ <ScalarModal controllerRef={controllerRef} method={method} path={path} securities={securities} servers={servers} specUrl={specUrl} />
33
+ </Suspense>, document.body)}
34
+ </div>;
35
+ }
36
+ function ScalarModal(props) {
37
+ const { method, path, securities, servers, specUrl, controllerRef } = props;
38
+ const prefillInputContext = useOpenAPIPrefillContext()();
39
+ const prefillConfig = resolveTryItPrefillForOperation({
40
+ operation: {
41
+ securities,
42
+ servers
43
+ },
44
+ prefillInputContext
45
+ });
46
+ return <ApiClientModalProvider configuration={{
47
+ url: specUrl,
48
+ ...prefillConfig
49
+ }} initialRequest={{
50
+ method: toScalarHttpMethod(method),
51
+ path
52
+ }}>
53
+ <ScalarModalController method={method} path={path} controllerRef={controllerRef} />
54
+ </ApiClientModalProvider>;
55
+ }
56
+ function toScalarHttpMethod(method) {
57
+ return method.toUpperCase();
58
+ }
59
+ function ScalarModalController(props) {
60
+ const { method, path, controllerRef } = props;
61
+ const openScalarClient = useApiClientModal()?.open;
62
+ const { onOpenClient: trackClientOpening } = useOpenAPIOperationContext();
63
+ const openClient = useMemo(() => {
64
+ if (openScalarClient) return () => {
65
+ openScalarClient({
66
+ method: toScalarHttpMethod(method),
67
+ path,
68
+ _source: "gitbook"
69
+ });
70
+ trackClientOpening({
71
+ method,
72
+ path
73
+ });
74
+ };
75
+ return null;
76
+ }, [
77
+ openScalarClient,
78
+ method,
79
+ path,
80
+ trackClientOpening
81
+ ]);
82
+ useImperativeHandle(controllerRef, () => ({ openClient: openClient ? () => openClient() : void 0 }), [openClient]);
83
+ useEffect(() => {
84
+ openClient?.();
85
+ }, [openClient]);
86
+ return null;
87
+ }
88
+
89
+ //#endregion
90
+ export { ScalarApiButton };
@@ -0,0 +1,37 @@
1
+ import clsx from "classnames";
2
+ import { forwardRef } from "react";
3
+
4
+ //#region src/StaticSection.tsx
5
+ function Section(props) {
6
+ return <div {...props} className={clsx("openapi-section", props.className)} />;
7
+ }
8
+ function SectionHeader(props) {
9
+ return <div {...props} className={clsx("openapi-section-header", props.className ? `${props.className}-header` : void 0)} />;
10
+ }
11
+ function SectionHeaderContent(props) {
12
+ return <div {...props} className={clsx("openapi-section-header-content", props.className && `${props.className}-header-content`)} />;
13
+ }
14
+ const SectionBody = forwardRef(function SectionBody$1(props, ref) {
15
+ return <div ref={ref} {...props} className={clsx("openapi-section-body", props.className && `${props.className}-body`)} />;
16
+ });
17
+ function SectionFooter(props) {
18
+ return <div {...props} className={clsx("openapi-section-footer", props.className && `${props.className}-footer`)} />;
19
+ }
20
+ function SectionFooterContent(props) {
21
+ return <div {...props} className={clsx("openapi-section-footer-content", props.className && `${props.className}-footer-content`)} />;
22
+ }
23
+ function StaticSection(props) {
24
+ const { className, header, children, footer } = props;
25
+ return <Section className={className}>
26
+ {header ? <SectionHeader className={className}>
27
+ <SectionHeaderContent className={className}>{header}</SectionHeaderContent>
28
+ </SectionHeader> : null}
29
+ <SectionBody className={className}>{children}</SectionBody>
30
+ {footer ? <SectionFooter className={className}>
31
+ <SectionFooterContent className={className}>{footer}</SectionFooterContent>
32
+ </SectionFooter> : null}
33
+ </Section>;
34
+ }
35
+
36
+ //#endregion
37
+ export { Section, SectionBody, SectionHeader, SectionHeaderContent, StaticSection };
@@ -0,0 +1,305 @@
1
+ import { json2xml } from "./json2xml.js";
2
+ import { stringifyOpenAPI } from "./stringifyOpenAPI.js";
3
+ import { isCSV, isFormData, isFormUrlEncoded, isGraphQL, isJSON, isPDF, isPlainObject, isText, isXML, isYAML } from "./contentTypeChecks.js";
4
+ import yaml from "js-yaml";
5
+
6
+ //#region src/code-samples.ts
7
+ const codeSampleGenerators = [
8
+ {
9
+ id: "http",
10
+ label: "HTTP",
11
+ syntax: "http",
12
+ generate: ({ method, url: { origin, path }, headers = {}, body }) => {
13
+ if (body) {
14
+ const bodyContent = body ? stringifyOpenAPI(body) : "";
15
+ const encoder = new TextEncoder();
16
+ const bodyString$1 = BodyGenerators.getHTTPBody(body, headers);
17
+ if (bodyString$1) body = bodyString$1;
18
+ headers = {
19
+ ...headers,
20
+ "Content-Length": encoder.encode(bodyContent).length.toString()
21
+ };
22
+ }
23
+ if (!headers.hasOwnProperty("Accept")) headers.Accept = "*/*";
24
+ const headerString = headers ? `${Object.entries(headers).map(([key, value]) => key.toLowerCase() !== "host" ? `${key}: ${value}` : "").join("\n")}\n` : "";
25
+ const bodyString = body ? `\n${body}` : "";
26
+ return `${method.toUpperCase()} ${decodeURI(path)} HTTP/1.1
27
+ Host: ${origin.replaceAll(/https*:\/\//g, "")}
28
+ ${headerString}${bodyString}`;
29
+ }
30
+ },
31
+ {
32
+ id: "curl",
33
+ label: "cURL",
34
+ syntax: "bash",
35
+ generate: ({ method, url: { origin, path }, headers, body }) => {
36
+ const lines = ["curl -L"];
37
+ if (method.toUpperCase() !== "GET") lines.push(`--request ${method.toUpperCase()}`);
38
+ lines.push(`--url '${origin}${path}'`);
39
+ if (body) {
40
+ const bodyContent = BodyGenerators.getCurlBody(body, headers);
41
+ if (bodyContent) {
42
+ body = bodyContent.body;
43
+ headers = bodyContent.headers;
44
+ }
45
+ }
46
+ if (headers && Object.keys(headers).length > 0) Object.entries(headers).forEach(([key, value]) => {
47
+ lines.push(`--header '${key}: ${value}'`);
48
+ });
49
+ if (body) if (Array.isArray(body)) lines.push(...body);
50
+ else lines.push(body);
51
+ return buildHeredoc(lines);
52
+ }
53
+ },
54
+ {
55
+ id: "javascript",
56
+ label: "JavaScript",
57
+ syntax: "javascript",
58
+ generate: ({ method, url: { origin, path }, headers, body }) => {
59
+ let code = "";
60
+ if (body) {
61
+ const lines = BodyGenerators.getJavaScriptBody(body, headers);
62
+ if (lines) {
63
+ code += lines.code;
64
+ body = lines.body;
65
+ headers = lines.headers;
66
+ }
67
+ }
68
+ code += `const response = await fetch('${origin}${path}', {
69
+ method: '${method.toUpperCase()}',\n`;
70
+ if (headers && Object.keys(headers).length > 0) code += indent(`headers: ${stringifyOpenAPI(headers, null, 2)},\n`, 4);
71
+ if (body) code += indent(`body: ${body}\n`, 4);
72
+ code += "});\n\n";
73
+ code += "const data = await response.json();";
74
+ return code;
75
+ }
76
+ },
77
+ {
78
+ id: "python",
79
+ label: "Python",
80
+ syntax: "python",
81
+ generate: ({ method, url: { origin, path }, headers, body }) => {
82
+ const contentType = headers?.["Content-Type"];
83
+ let code = `${isJSON(contentType) ? "import json\n" : ""}import requests\n\n`;
84
+ if (body) {
85
+ const lines = BodyGenerators.getPythonBody(body, headers);
86
+ if (lines) {
87
+ code += lines.code;
88
+ body = lines.body;
89
+ headers = lines.headers;
90
+ }
91
+ }
92
+ code += `response = requests.${method.toLowerCase()}(\n`;
93
+ code += indent(`"${origin}${path}",\n`, 4);
94
+ if (headers && Object.keys(headers).length > 0) code += indent(`headers=${stringifyOpenAPI(headers)},\n`, 4);
95
+ if (body) if (body === "files") code += indent(`files=${body}\n`, 4);
96
+ else if (isJSON(contentType)) code += indent(`data=json.dumps(${body})\n`, 4);
97
+ else code += indent(`data=${body}\n`, 4);
98
+ code += ")\n\n";
99
+ code += "data = response.json()";
100
+ return code;
101
+ }
102
+ }
103
+ ];
104
+ function indent(code, spaces) {
105
+ const indent$1 = " ".repeat(spaces);
106
+ return code.split("\n").map((line) => line ? indent$1 + line : "").join("\n");
107
+ }
108
+ function parseHostAndPath(url) {
109
+ try {
110
+ const urlObj = new URL(url);
111
+ const path = urlObj.pathname || "/";
112
+ return {
113
+ host: urlObj.host,
114
+ path
115
+ };
116
+ } catch (_e) {
117
+ const splitted = url.split("//");
118
+ const parts = (splitted[1] ? splitted[1] : url).split("/");
119
+ return {
120
+ host: parts.shift(),
121
+ path: `/${parts.join("/")}`
122
+ };
123
+ }
124
+ }
125
+ const BodyGenerators = {
126
+ getCurlBody(body, headers) {
127
+ if (!body || !headers) return void 0;
128
+ const headersCopy = { ...headers };
129
+ const contentType = headersCopy["Content-Type"] || "";
130
+ if (isFormData(contentType)) body = isPlainObject(body) ? Object.entries(body).map(([key, value]) => `--form '${key}=${String(value)}'`) : `--form 'file=@${body}'`;
131
+ else if (isFormUrlEncoded(contentType)) body = isPlainObject(body) ? `--data '${Object.entries(body).map(([key, value]) => `${key}=${String(value)}`).join("&")}'` : String(body);
132
+ else if (isText(contentType)) body = `--data '${String(body).replace(/"/g, "")}'`;
133
+ else if (isXML(contentType)) body = `--data-binary $'${convertBodyToXML(body)}'`;
134
+ else if (isCSV(contentType)) body = `--data-binary $'${stringifyOpenAPI(body).replace(/"/g, "").replace(/\\n/g, "\n")}'`;
135
+ else if (isGraphQL(contentType)) {
136
+ body = `--data '${stringifyOpenAPI(body)}'`;
137
+ headersCopy["Content-Type"] = "application/json";
138
+ } else if (isPDF(contentType)) body = `--data-binary '@${String(body)}'`;
139
+ else if (isYAML(contentType)) body = `--data-binary $'${yaml.dump(body).replace(/'/g, "").replace(/\\n/g, "\n")}'`;
140
+ else {
141
+ const jsonString = stringifyOpenAPI(body, null, 2).replace(/\\n/g, "\n");
142
+ if (jsonString.includes("'")) body = [
143
+ "--data @- <<'EOF'",
144
+ ...jsonString.split("\n"),
145
+ "EOF"
146
+ ];
147
+ else body = `--data '${jsonString}'`;
148
+ }
149
+ return {
150
+ body,
151
+ headers: headersCopy
152
+ };
153
+ },
154
+ getJavaScriptBody: (body, headers) => {
155
+ if (!body || !headers) return;
156
+ let code = "";
157
+ const headersCopy = { ...headers };
158
+ const contentType = headersCopy["Content-Type"] || "";
159
+ if (isFormData(contentType)) {
160
+ code += "const formData = new FormData();\n\n";
161
+ if (isPlainObject(body)) Object.entries(body).forEach(([key, value]) => {
162
+ code += `formData.append("${key}", "${String(value)}");\n`;
163
+ });
164
+ else if (typeof body === "string") code += `formData.append("file", "${body}");\n`;
165
+ code += "\n";
166
+ body = "formData";
167
+ } else if (isFormUrlEncoded(contentType)) {
168
+ code += "const params = new URLSearchParams();\n\n";
169
+ if (isPlainObject(body)) Object.entries(body).forEach(([key, value]) => {
170
+ code += `params.append("${key}", "${String(value)}");\n`;
171
+ });
172
+ code += "\n";
173
+ body = "params.toString()";
174
+ } else if (isGraphQL(contentType)) if (isPlainObject(body)) {
175
+ Object.entries(body).forEach(([key, value]) => {
176
+ code += `const ${key} = \`\n${indent(String(value), 4)}\`;\n\n`;
177
+ });
178
+ body = `JSON.stringify({ ${Object.keys(body).join(", ")} })`;
179
+ headersCopy["Content-Type"] = "application/json";
180
+ } else {
181
+ code += `const query = \`\n${indent(String(body), 4)}\`;\n\n`;
182
+ body = "JSON.stringify(query)";
183
+ }
184
+ else if (isCSV(contentType)) {
185
+ code += "const csv = `\n";
186
+ code += indent(String(body), 4);
187
+ code += "`;\n\n";
188
+ body = "csv";
189
+ } else if (isPDF(contentType)) {
190
+ code += "const formData = new FormData();\n\n";
191
+ code += `formData.append("file", "${body}");\n\n`;
192
+ body = "formData";
193
+ } else if (isXML(contentType)) {
194
+ code += "const xml = `\n";
195
+ code += indent(convertBodyToXML(body), 4);
196
+ code += "`;\n\n";
197
+ body = "xml";
198
+ } else if (isYAML(contentType)) {
199
+ code += `const yamlBody = \`\n${indent(yaml.dump(body), 4)}\`;\n\n`;
200
+ body = "yamlBody";
201
+ } else if (isText(contentType)) body = stringifyOpenAPI(body, null, 2);
202
+ else body = `JSON.stringify(${stringifyOpenAPI(body, null, 2)})`;
203
+ return {
204
+ body,
205
+ code,
206
+ headers: headersCopy
207
+ };
208
+ },
209
+ getPythonBody: (body, headers) => {
210
+ if (!body || !headers) return;
211
+ let code = "";
212
+ const contentType = headers["Content-Type"] || "";
213
+ if (isFormData(contentType)) {
214
+ code += "files = {\n";
215
+ if (isPlainObject(body)) Object.entries(body).forEach(([key, value]) => {
216
+ code += `${indent(`"${key}": "${String(value)}",`, 4)}\n`;
217
+ });
218
+ code += "}\n\n";
219
+ body = "files";
220
+ } else if (isPDF(contentType)) {
221
+ code += "files = {\n";
222
+ code += `${indent(`"file": "${body}",`, 4)}\n`;
223
+ code += "}\n\n";
224
+ body = "files";
225
+ } else if (isXML(contentType)) body = JSON.stringify(convertBodyToXML(body));
226
+ else if (isYAML(contentType)) {
227
+ code += `yamlBody = \"\"\"\n${indent(yaml.dump(body), 4)}\"\"\"\n\n`;
228
+ body = "yamlBody";
229
+ } else body = stringifyOpenAPI(body, (_key, value) => {
230
+ switch (value) {
231
+ case true: return "$$__TRUE__$$";
232
+ case false: return "$$__FALSE__$$";
233
+ case null: return "$$__NULL__$$";
234
+ default: return value;
235
+ }
236
+ }, 2).replaceAll("\"$$__TRUE__$$\"", "True").replaceAll("\"$$__FALSE__$$\"", "False").replaceAll("\"$$__NULL__$$\"", "None");
237
+ return {
238
+ body,
239
+ code,
240
+ headers
241
+ };
242
+ },
243
+ getHTTPBody: (body, headers) => {
244
+ if (!body || !headers) return void 0;
245
+ const contentType = headers["Content-Type"] || "";
246
+ const typeHandlers = {
247
+ pdf: () => `${stringifyOpenAPI(body, null, 2)}`,
248
+ formUrlEncoded: () => {
249
+ return `"${(isPlainObject(body) ? Object.entries(body).map(([key, value]) => `${key}=${stringifyOpenAPI(value)}`).join("&") : stringifyOpenAPI(body)).replace(/"/g, "'")}"`;
250
+ },
251
+ text: () => `"${String(body)}"`,
252
+ xml: () => {
253
+ return `"${convertBodyToXML(body)}"`;
254
+ },
255
+ yaml: () => `"${yaml.dump(body).replace(/"/g, "\\\"")}"`,
256
+ csv: () => `"${stringifyOpenAPI(body).replace(/"/g, "")}"`,
257
+ default: () => `${stringifyOpenAPI(body, null, 2)}`
258
+ };
259
+ if (isPDF(contentType)) return typeHandlers.pdf();
260
+ if (isFormUrlEncoded(contentType)) return typeHandlers.formUrlEncoded();
261
+ if (isText(contentType)) return typeHandlers.text();
262
+ if (isXML(contentType)) return typeHandlers.xml();
263
+ if (isYAML(contentType)) return typeHandlers.yaml();
264
+ if (isCSV(contentType)) return typeHandlers.csv();
265
+ return typeHandlers.default();
266
+ }
267
+ };
268
+ /**
269
+ * Converts a body to XML format
270
+ */
271
+ function convertBodyToXML(body) {
272
+ if (typeof body === "string" && body.trim().startsWith("<")) return body;
273
+ if (typeof body !== "object" || body === null) try {
274
+ body = JSON.parse(body);
275
+ } catch {
276
+ return body;
277
+ }
278
+ return json2xml(body).replace(/"/g, "").replace(/\\n/g, "\n").replace(/\\t/g, " ");
279
+ }
280
+ /**
281
+ * Builds a heredoc string from an array of lines
282
+ */
283
+ function buildHeredoc(lines) {
284
+ const separator = " \\\n";
285
+ let result = "";
286
+ let inHeredoc = false;
287
+ for (let i = 0; i < lines.length; i++) {
288
+ const line = lines[i];
289
+ if (!line) continue;
290
+ const isHeredocStart = line.includes("<<'EOF'");
291
+ const isHeredocEnd = inHeredoc && line === "EOF";
292
+ if (isHeredocStart) {
293
+ inHeredoc = true;
294
+ result += `${i > 0 ? indent(line, 2) : line}\n`;
295
+ } else if (isHeredocEnd) {
296
+ inHeredoc = false;
297
+ result += line;
298
+ } else if (inHeredoc) result += `${indent(line, 2)}\n`;
299
+ else result += `${i > 0 ? indent(line, 2) : line}${i < lines.length - 1 ? separator : ""}`;
300
+ }
301
+ return result;
302
+ }
303
+
304
+ //#endregion
305
+ export { codeSampleGenerators, parseHostAndPath };
@@ -0,0 +1,23 @@
1
+ import { t } from "../translate.js";
2
+ import { getOpenAPIClientContext } from "../context.js";
3
+ import { OpenAPISpec } from "../OpenAPISpec.js";
4
+ import { OpenAPIOperationDescription } from "./OpenAPIOperationDescription.js";
5
+
6
+ //#region src/common/OpenAPIColumnSpec.tsx
7
+ function OpenAPIColumnSpec(props) {
8
+ const { data, context } = props;
9
+ const { operation } = data;
10
+ const clientContext = getOpenAPIClientContext(context);
11
+ return <div className="openapi-column-spec">
12
+ {operation["x-deprecated-sunset"] ? <div className="openapi-deprecated-sunset openapi-description openapi-markdown">
13
+ {t(context.translation, "deprecated_and_sunset_on", [<span key="date" className="openapi-deprecated-sunset-date">
14
+ {operation["x-deprecated-sunset"]}
15
+ </span>])}
16
+ </div> : null}
17
+ <OpenAPIOperationDescription operation={operation} context={context} />
18
+ <OpenAPISpec data={data} context={clientContext} />
19
+ </div>;
20
+ }
21
+
22
+ //#endregion
23
+ export { OpenAPIColumnSpec };
@@ -0,0 +1,18 @@
1
+ import { Markdown } from "../Markdown.js";
2
+ import { resolveDescription } from "../utils.js";
3
+
4
+ //#region src/common/OpenAPIOperationDescription.tsx
5
+ function OpenAPIOperationDescription(props) {
6
+ const { operation } = props;
7
+ if (operation["x-gitbook-description-document"]) return <div className="openapi-intro">
8
+ {props.context.renderDocument({ document: operation["x-gitbook-description-document"] })}
9
+ </div>;
10
+ const description = resolveDescription(operation);
11
+ if (!description) return null;
12
+ return <div className="openapi-intro">
13
+ <Markdown className="openapi-description" source={description} />
14
+ </div>;
15
+ }
16
+
17
+ //#endregion
18
+ export { OpenAPIOperationDescription };
@@ -0,0 +1,17 @@
1
+ //#region src/common/OpenAPIStability.tsx
2
+ const stabilityEnum = {
3
+ experimental: "Experimental",
4
+ alpha: "Alpha",
5
+ beta: "Beta"
6
+ };
7
+ function OpenAPIStability(props) {
8
+ const { stability } = props;
9
+ const foundStability = stabilityEnum[stability];
10
+ if (!foundStability) return null;
11
+ return <div className={`openapi-stability openapi-stability-${foundStability.toLowerCase()}`}>
12
+ {foundStability}
13
+ </div>;
14
+ }
15
+
16
+ //#endregion
17
+ export { OpenAPIStability };
@@ -0,0 +1,27 @@
1
+ import { OpenAPIPath } from "../OpenAPIPath.js";
2
+ import { OpenAPIStability } from "./OpenAPIStability.js";
3
+
4
+ //#region src/common/OpenAPISummary.tsx
5
+ function OpenAPISummary(props) {
6
+ const { data, context } = props;
7
+ const { operation } = data;
8
+ const title = (() => {
9
+ if (operation.summary) return operation.summary;
10
+ if ("name" in data) return data.name;
11
+ })();
12
+ return <div className="openapi-summary" id={operation.summary ? void 0 : context.id}>
13
+ {(operation.deprecated || operation["x-stability"]) && <div className="openapi-summary-tags">
14
+ {operation.deprecated && <div className="openapi-deprecated">Deprecated</div>}
15
+ {operation["x-stability"] && <OpenAPIStability stability={operation["x-stability"]} />}
16
+ </div>}
17
+ {title ? context.renderHeading({
18
+ deprecated: operation.deprecated ?? false,
19
+ stability: operation["x-stability"],
20
+ title
21
+ }) : null}
22
+ {"path" in data ? <OpenAPIPath data={data} context={context} /> : null}
23
+ </div>;
24
+ }
25
+
26
+ //#endregion
27
+ export { OpenAPISummary };
@@ -0,0 +1,34 @@
1
+ //#region src/contentTypeChecks.ts
2
+ function isJSON(contentType) {
3
+ return contentType?.toLowerCase().includes("application/json") || false;
4
+ }
5
+ function isXML(contentType) {
6
+ return contentType?.toLowerCase().includes("application/xml") || false;
7
+ }
8
+ function isYAML(contentType) {
9
+ return contentType?.toLowerCase().includes("application/yaml") || false;
10
+ }
11
+ function isGraphQL(contentType) {
12
+ return contentType?.toLowerCase().includes("application/graphql") || false;
13
+ }
14
+ function isCSV(contentType) {
15
+ return contentType?.toLowerCase().includes("text/csv") || false;
16
+ }
17
+ function isPDF(contentType) {
18
+ return contentType?.toLowerCase().includes("application/pdf") || false;
19
+ }
20
+ function isText(contentType) {
21
+ return contentType?.toLowerCase().includes("text/plain") || false;
22
+ }
23
+ function isFormUrlEncoded(contentType) {
24
+ return contentType?.toLowerCase().includes("application/x-www-form-urlencoded") || false;
25
+ }
26
+ function isFormData(contentType) {
27
+ return !!contentType && contentType.toLowerCase().includes("multipart/form-data");
28
+ }
29
+ function isPlainObject(value) {
30
+ return typeof value === "object" && value !== null && !Array.isArray(value);
31
+ }
32
+
33
+ //#endregion
34
+ export { isCSV, isFormData, isFormUrlEncoded, isGraphQL, isJSON, isPDF, isPlainObject, isText, isXML, isYAML };